摘要:為了寫好爬蟲,我們需要準備一個火狐瀏覽器,還需要準備抓包工具,抓包工具,我使用的是自帶的,加上,這兩款軟件的安裝和使用,建議你還是學習一下,后面我們應該會用到。
妹子圖網站----前言
從今天開始就要擼起袖子,直接寫Python爬蟲了,學習語言最好的辦法就是有目的的進行,所以,接下來我將用10+篇的博客,寫爬圖片這一件事情。希望可以做好。
為了寫好爬蟲,我們需要準備一個火狐瀏覽器,還需要準備抓包工具,抓包工具,我使用的是CentOS自帶的tcpdump,加上wireshark ,這兩款軟件的安裝和使用,建議你還是學習一下,后面我們應該會用到。
妹子圖網站---- 網絡請求模塊requestsPython中的大量開源的模塊使得編碼變的特別簡單,我們寫爬蟲第一個要了解的模塊就是requests。
妹子圖網站---- 安裝requests打開終端:使用命令
pip3 install requests
等待安裝完畢即可使用
接下來在終端中鍵入如下命令
# mkdir demo # cd demo # touch down.py
上面的linux命令是 創建一個名稱為demo的文件夾,之后創建一個down.py文件,你也可以使用GUI工具,像操作windows一樣,右鍵創建各種文件。
為了提高在linux上的開發效率,我們需要安裝一個visual studio code 的開發工具
對于怎么安裝vscode,參考官方的https://code.visualstudio.com... 有詳細的說明。
對于centos則如下:
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo sh -c "echo -e "[code] name=Visual Studio Code baseurl=https://packages.microsoft.com/yumrepos/vscode enabled=1 gpgcheck=1 gpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo"
然后用yum命令安裝
yum check-update sudo yum install code
安裝成功之后,在你的CentOS中會出現如下畫面
接著說我們上面的操作 ,因為我們這邊是用gnome圖形界面,所以后面的有些操作,我直接用windows的操作風格講解了
打開軟件>文件>打開文件>找到我們剛剛創建的down.py文件
之后,在VSCODE里面輸入
import requests #導入模塊 def run(): #聲明一個run方法 print("跑碼文件") #打印內容 if __name__ == "__main__": #主程序入口 run() #調用上面的run方法
tips:本教程不是Python3的基礎入門課,所以有些編碼基礎,默認你懂,比如Python沒有分號結尾,需要對齊格式。我會盡量把注釋寫的完整
按鍵盤上的ctrl+s保存文件,如果提示權限不足,那么按照提示輸入密碼即可
通過終端進入demo目錄,然后輸入
python3 down.py
顯示如下結果,代表編譯沒有問題
[root@bogon demo]# python3 down.py 跑碼文件
接下來,我們開始測試requests模塊是否可以使用
修改上述代碼中的
import requests def run(): response = requests.get("http://www.baidu.com") print(response.text) if __name__ == "__main__": run()
運行結果(出現下圖代表你運行成功了):
接下來,我們實際下載一張圖片試試,比如下面這張圖片
修改代碼,在這之前,我們修改一些內容
由于每次修改文件,都提示必須管理員權限,所以你可以使用linux命令修改權限。
[root@bogon linuxboy]# chmod -R 777 demo/
import requests def run(): response = requests.get("http://www.newsimg.cn/big201710leaderreports/xibdj20171030.jpg") with open("a.jpg","wb") as f : f.write(response.content) f.close if __name__ == "__main__": run()
運行代碼之后,發現在文件夾內部生成了一個文件
但是打開文件之后發現,這個文件并不能查閱,這代表這個文件壓根沒有下載下來
我們繼續修改代碼,因為有的服務器圖片,都做了一些限制,我們可以用瀏覽器打開,但是使用Python代碼并不能完整的下載下來。
修改代碼
import requests def run(): # 頭文件,header是字典類型 headers = { "Host":"www.newsimg.cn", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5383.400 QQBrowser/10.0.1313.400" } response = requests.get("http://www.newsimg.cn/big201710leaderreports/xibdj20171030.jpg",headers=headers) with open("a.jpg","wb") as f : f.write(response.content) f.close() if __name__ == "__main__": run()
好了,這次在終端編譯一下python文件
python3 down.py
發現圖片下載下來了
我們重點查看上述代碼中 requests.get部分,添加了一個headers的實參。這樣我們程序就下載下來了完整的圖片。
妹子圖網站---- Python爬蟲頁面分析有了上面這個簡單的案例,我們接下來的操作就變的簡單多了。爬蟲是如何進行的呢?
輸入域名->下載源代碼->分析圖片路徑->下載圖片
上面就是他的步驟
輸入域名我們今天要爬的網站叫做 http://www.meizitu.com/a/pure...
為啥爬取這個網站,因為好爬。
好了,接下來分析這個頁面
做爬蟲很重要的一點,就是你要找到分頁的地方,因為有分頁代表著有規律,有規律,我們就好爬了(可以做的更智能一些,輸入首頁網址,爬蟲自己就能分析到這個網站中的所有地址)
上面圖片中,我們發現了分頁,那么找規律吧
使用火狐瀏覽器的開發者工具,發現分頁規律
http://www.meizitu.com/a/pure_1.html http://www.meizitu.com/a/pure_2.html http://www.meizitu.com/a/pure_3.html http://www.meizitu.com/a/pure_4.html
好了,接下來用Python實現這部分(以下寫法有部分面向對象的寫法,沒有基礎的同學,請百度找些基礎來看,不過對于想學習的你來說,這些簡單極了)
import requests all_urls = [] #我們拼接好的圖片集和列表路徑 class Spider(): #構造函數,初始化數據使用 def __init__(self,target_url,headers): self.target_url = target_url self.headers = headers #獲取所有的想要抓取的URL def getUrls(self,start_page,page_num): global all_urls #循環得到URL for i in range(start_page,page_num+1): url = self.target_url % i all_urls.append(url) if __name__ == "__main__": headers = { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0", "HOST":"www.meizitu.com" } target_url = "http://www.meizitu.com/a/pure_%d.html" #圖片集和列表規則 spider = Spider(target_url,headers) spider.getUrls(1,16) print(all_urls)
上面的代碼,可能需要有一定的Python基礎可以看懂,不過你其實仔細看一下,就幾個要點
第一個是 class Spider(): 我們聲明了一個類,然后我們使用 def __init__去聲明一個構造函數,這些我覺得你找個教程30分鐘也就學會了。
拼接URL,我們可以用很多辦法,我這里用的是最直接的,字符串拼接。
注意上述代碼中有一個全局的變量 all_urls 我用它來存儲我們的所有分頁的URL
接下來,是爬蟲最核心的部分代碼了
我們需要分析頁面中的邏輯。首先打開 http://www.meizitu.com/a/pure... ,右鍵審查元素。
發現上圖紅色框框里面的鏈接
點擊圖片之后,發現進入一個圖片詳情頁面,發現竟然是一組圖片,那么現在的問題是
我們要解決第一步,需要在 http://www.meizitu.com/a/pure... 這種頁面中爬取所有的 http://www.meizitu.com/a/5585... 這種地址
這里我們采用多線程的方式爬?。ㄟ@里還用了一種設計模式,叫觀察者模式)
import threading #多線程模塊 import re #正則表達式模塊 import time #時間模塊
首先引入三個模塊,分別是多線程,正則表達式,時間模塊
新增加一個全局的變量,并且由于是多線程操作,我們需要引入線程鎖
all_img_urls = [] #圖片列表頁面的數組 g_lock = threading.Lock() #初始化一個鎖
聲明一個生產者的類,用來不斷的獲取圖片詳情頁地址,然后添加到 all_img_urls 這個全局變量中
#生產者,負責從每個頁面提取圖片列表鏈接 class Producer(threading.Thread): def run(self): headers = { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0", "HOST":"www.meizitu.com" } global all_urls while len(all_urls) > 0 : g_lock.acquire() #在訪問all_urls的時候,需要使用鎖機制 page_url = all_urls.pop() #通過pop方法移除最后一個元素,并且返回該值 g_lock.release() #使用完成之后及時把鎖給釋放,方便其他線程使用 try: print("分析"+page_url) response = requests.get(page_url , headers = headers,timeout=3) all_pic_link = re.findall("",response.text,re.S) global all_img_urls g_lock.acquire() #這里還有一個鎖 all_img_urls += all_pic_link #這個地方注意數組的拼接,沒有用append直接用的+=也算是python的一個新語法吧 print(all_img_urls) g_lock.release() #釋放鎖 time.sleep(0.5) except: pass
上述代碼用到了繼承的概念,我從threading.Thread中繼承了一個子類,繼承的基礎學習,你可以去翻翻 http://www.runoob.com/python3... 菜鳥教程就行。
線程鎖,在上面的代碼中,當我們操作all_urls.pop()的時候,我們是不希望其他線程對他進行同時操作的,否則會出現意外,所以我們使用g_lock.acquire()鎖定資源,然后使用完成之后,記住一定要立馬釋放g_lock.release(),否則這個資源就一直被占用著,程序無法進行下去了。
匹配網頁中的URL,我使用的是正則表達式,后面我們會使用其他的辦法,進行匹配。
re.findall() 方法是獲取所有匹配到的內容,正則表達式,你可以找一個30分鐘入門的教程,看看就行。
代碼容易出錯的地方,我放到了
try: except: 里面,當然,你也可以自定義錯誤。
如果上面的代碼,都沒有問題,那么我們就可以在程序入口的地方編寫
for x in range(2): t = Producer() t.start()
執行程序,因為我們的Producer繼承自threading.Thread類,所以,你必須要實現的一個方法是 def run 這個我相信在上面的代碼中,你已經看到了。然后我們可以執行啦~~~
運行結果:
這樣,圖片詳情頁面的列表就已經被我們存儲起來了。
接下來,我們需要執行這樣一步操作,我想要等待圖片詳情頁面全部獲取完畢,在進行接下來的分析操作。
這里增加代碼
#threads= [] #開啟兩個線程去訪問 for x in range(2): t = Producer() t.start() #threads.append(t) # for tt in threads: # tt.join() print("進行到我這里了")
注釋關鍵代碼,運行如下
[linuxboy@bogon demo]$ python3 down.py 分析http://www.meizitu.com/a/pure_2.html 分析http://www.meizitu.com/a/pure_1.html 進行到我這里了 ["http://www.meizitu.com/a/5585.html",
把上面的tt.join等代碼注釋打開
[linuxboy@bogon demo]$ python3 down.py 分析http://www.meizitu.com/a/pure_2.html 分析http://www.meizitu.com/a/pure_1.html ["http://www.meizitu.com/a/5429.html", ...... 進行到我這里了
發現一個本質的區別,就是,我們由于是多線程的程序,所以,當程序跑起來之后,print("進行到我這里了")不會等到其他線程結束,就會運行到,但是當我們改造成上面的代碼之后,也就是加入了關鍵的代碼 tt.join() 那么主線程的代碼會等到所以子線程運行完畢之后,在接著向下運行。這就滿足了,我剛才說的,先獲取到所有的圖片詳情頁面的集合,這一條件了。
join所完成的工作就是線程同步,即主線程遇到join之后進入阻塞狀態,一直等待其他的子線程執行結束之后,主線程在繼續執行。這個大家在以后可能經常會碰到。
下面編寫一個消費者/觀察者,也就是不斷關注剛才我們獲取的那些圖片詳情頁面的數組。
添加一個全局變量,用來存儲獲取到的圖片鏈接
pic_links = [] #圖片地址列表
#消費者 class Consumer(threading.Thread) : def run(self): headers = { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0", "HOST":"www.meizitu.com" } global all_img_urls #調用全局的圖片詳情頁面的數組 print("%s is running " % threading.current_thread) while len(all_img_urls) >0 : g_lock.acquire() img_url = all_img_urls.pop() g_lock.release() try: response = requests.get(img_url , headers = headers ) response.encoding="gb2312" #由于我們調用的頁面編碼是GB2312,所以需要設置一下編碼 title = re.search("(.*?) | 妹子圖 ",response.text).group(1) all_pic_src = re.findall("
",response.text,re.S) pic_dict = {title:all_pic_src} #python字典 global pic_links g_lock.acquire() pic_links.append(pic_dict) #字典數組 print(title+" 獲取成功") g_lock.release() except: pass time.sleep(0.5)
看到沒有,上面的代碼其實和我們剛才寫的極其相似,后面,我會在github上面把這部分代碼修改的更加簡潔一些,不過這才是第二課,后面我們的路長著呢。
代碼中比較重要的一些部分,我已經使用注釋寫好了,大家可以直接參考。大家一定要注意我上面使用了兩個正則表達式,分別用來匹配title和圖片的url這個title是為了后面創建不同的文件夾使用的,所以大家注意吧。
#開啟10個線程去獲取鏈接 for x in range(10): ta = Consumer() ta.start()
運行結果:
[linuxboy@bogon demo]$ python3 down.py 分析http://www.meizitu.com/a/pure_2.html 分析http://www.meizitu.com/a/pure_1.html ["http://www.meizitu.com/a/5585.html", ......is running is running is running is running is running is running is running is running 進行到我這里了 is running is running 清純美如畫,攝影師的御用麻豆 獲取成功 宅男女神葉梓萱近日拍攝一組火爆寫真 獲取成功 美(bao)胸(ru)女王帶來制服誘惑 獲取成功 每天睜開眼看到美好的你,便是幸福 獲取成功 可愛女孩,愿暖風呵護純真和執著 獲取成功 清純妹子如一縷陽光溫暖這個冬天 獲取成功 .....
是不是感覺距離成功有進了一大步
接下來就是,我們開篇提到的那個存儲圖片的操作了,還是同樣的步驟,寫一個自定義的類
class DownPic(threading.Thread) : def run(self): headers = { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0", "HOST":"mm.chinasareview.com" } while True: # 這個地方寫成死循環,為的是不斷監控圖片鏈接數組是否更新 global pic_links # 上鎖 g_lock.acquire() if len(pic_links) == 0: #如果沒有圖片了,就解鎖 # 不管什么情況,都要釋放鎖 g_lock.release() continue else: pic = pic_links.pop() g_lock.release() # 遍歷字典列表 for key,values in pic.items(): path=key.rstrip("") is_exists=os.path.exists(path) # 判斷結果 if not is_exists: # 如果不存在則創建目錄 # 創建目錄操作函數 os.makedirs(path) print (path+"目錄創建成功") else: # 如果目錄存在則不創建,并提示目錄已存在 print(path+" 目錄已存在") for pic in values : filename = path+"/"+pic.split("/")[-1] if os.path.exists(filename): continue else: response = requests.get(pic,headers=headers) with open(filename,"wb") as f : f.write(response.content) f.close
我們獲取圖片鏈接之后,就需要下載了,我上面的代碼是首先創建了一個之前獲取到title的文件目錄,然后在目錄里面通過下面的代碼,去創建一個文件。
涉及到文件操作,引入一個新的模塊
import os #目錄操作模塊
# 遍歷字典列表 for key,values in pic.items(): path=key.rstrip("") is_exists=os.path.exists(path) # 判斷結果 if not is_exists: # 如果不存在則創建目錄 # 創建目錄操作函數 os.makedirs(path) print (path+"目錄創建成功") else: # 如果目錄存在則不創建,并提示目錄已存在 print(path+" 目錄已存在") for pic in values : filename = path+"/"+pic.split("/")[-1] if os.path.exists(filename): continue else: response = requests.get(pic,headers=headers) with open(filename,"wb") as f : f.write(response.content) f.close
因為我們的圖片鏈接數組,里面存放是的字典格式,也就是下面這種格式
[{"妹子圖1":["http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/01.jpg","http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/02.jpg"."http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/03.jpg"]},{"妹子圖2":["http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/01.jpg","http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/02.jpg"."http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/03.jpg"]},{"妹子圖3":["http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/01.jpg","http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/02.jpg"."http://mm.chinasareview.com/wp-content/uploads/2016a/08/24/03.jpg"]}]
需要先循環第一層,獲取title,創建目錄之后,在循環第二層去下載圖片,代碼中,我們在修改一下,把異常處理添加上。
try: response = requests.get(pic,headers=headers) with open(filename,"wb") as f : f.write(response.content) f.close except Exception as e: print(e) pass
然后在主程序中編寫代碼
#開啟10個線程保存圖片 for x in range(10): down = DownPic() down.start()
運行結果:
[linuxboy@bogon demo]$ python3 down.py 分析http://www.meizitu.com/a/pure_2.html 分析http://www.meizitu.com/a/pure_1.html ["http://www.meizitu.com/a/5585.html", "http://www.meizitu.com/a/5577.html", "http://www.meizitu.com/a/5576.html", "http://www.meizitu.com/a/5574.html", "http://www.meizitu.com/a/5569.html", .......is running is running is running 進行到我這里了 清純妹子如一縷陽光溫暖這個冬天 獲取成功 清純妹子如一縷陽光溫暖這個冬天目錄創建成功 可愛女孩,愿暖風呵護純真和執著 獲取成功 可愛女孩,愿暖風呵護純真和執著目錄創建成功 超美,純純的你與藍藍的天相得益彰 獲取成功 超美,純純的你與藍藍的天相得益彰目錄創建成功 美麗凍人,雪地里的跆拳道少女 獲取成功 五官精致的美眉,仿佛童話里的公主 獲取成功 有自信迷人的笑容,每天都是燦爛的 獲取成功 五官精致的美眉,仿佛童話里的公主目錄創建成功 有自信迷人的笑容,每天都是燦爛的目錄創建成功 清純美如畫,攝影師的御用麻豆 獲取成功
文件目錄下面同時出現
點開一個目錄
好了,今天的一個簡單的爬蟲成了
最后我們在代碼的頭部寫上
# -*- coding: UTF-8 -*-
防止出現 Non-ASCII character "xe5" in file報錯問題。
歡迎關注「非本科程序員」 回復 【妹子圖】獲取資源
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43863.html
摘要:為了寫好爬蟲,我們需要準備一個火狐瀏覽器,還需要準備抓包工具,抓包工具,我使用的是自帶的,加上,這兩款軟件的安裝和使用,建議你還是學習一下,后面我們應該會用到。 妹子圖網站----前言 從今天開始就要擼起袖子,直接寫Python爬蟲了,學習語言最好的辦法就是有目的的進行,所以,接下來我將用10+篇的博客,寫爬圖片這一件事情。希望可以做好。 為了寫好爬蟲,我們需要準備一個火狐瀏覽器,還需...
摘要:爬蟲入門聽說你寫代碼沒動力本文就給你動力,爬取妹子圖。分別進入每個套圖中去,下載相應的圖片。最大線程數設置為正在下載頁好了,之后運行,我們的爬蟲就會孜孜不倦的為我們下載漂亮妹子啦。 Python 爬蟲入門 聽說你寫代碼沒動力?本文就給你動力,爬取妹子圖。如果這也沒動力那就沒救了。 GitHub 地址: https://github.com/injetlee/Python/blob/ma...
摘要:作為爬蟲的入門教程,我想有必要來個爬蟲程序壓壓驚,爬取性感美女的圖片,然后保存到自己的電腦里面。爽歪歪先看下效果吧,這是我把爬取的圖片自動存儲到的文件夾里邊爬蟲三步驟抓取,分析,存儲。相關文章入門基礎有趣的教程 作為 Python 爬蟲的入門教程,我想有必要來個爬蟲程序壓壓驚,爬取性感美女的圖片,然后保存到自己的電腦里面。爽歪歪~ 先看下效果吧,這是我把爬取的圖片自動存儲到的文件夾里邊...
摘要:很多人學習爬蟲的第一驅動力就是爬取各大網站的妹子圖片,比如比較有名的。最后我們只需要運行程序,即可執行爬取,程序運行命名如下完整代碼我已上傳到微信公眾號后臺,在癡海公眾號后臺回復即可獲取。本文首發于公眾號癡海,后臺回復即可獲取最新編程資源。 showImg(https://segmentfault.com/img/remote/1460000016780800); 閱讀文本大概需要 1...
閱讀 713·2023-04-25 17:54
閱讀 2971·2021-11-18 10:02
閱讀 1132·2021-09-28 09:35
閱讀 649·2021-09-22 15:18
閱讀 2847·2021-09-03 10:49
閱讀 3051·2021-08-10 09:42
閱讀 2572·2019-08-29 16:24
閱讀 1255·2019-08-29 15:08