標籤:python 地方 nts 分享 XML 公眾號 工具 原始碼 image
介紹
??本篇部落格將會介紹一個Python爬蟲,用來爬取各個國家的國旗,主要的目標是為了展示如何在Python的requests模組中使用POST方法來爬取網頁內容。
??為了知道POST方法所需要傳遞的HTTP要求標頭部和請求體,我們可以使用Fiddler來進行抓包,抓取上網過程中HTTP請求中的POST方法。為了驗證Fiddler抓取到的POST請求,可以使用Postman進行測實驗證。在Postman中完成測試後,我們就可以用Python的request.POST()方法來寫我們的爬蟲了。
流程
??作為上述過程的一個示範,我們使用的網址為: http://country.911cha.com/ , 頁面如下:
在表單中輸入德國,跳轉後的頁面如下:
我們可以發現,在搜尋的結果中,會出現德國這個搜尋結果。點擊該搜尋結果,跳轉後的頁面如下:
在這個頁面中有我們需要的德國的國旗。但是,怎麼知道該網頁的具體網址呢?換句話說,就是怎樣得到http://country.911cha.com/GER.html ?別擔心,在剛才出來的德國這個搜尋結果中,我們查看其原始碼,不難發現,在HTML原始碼中,有我們想要的東西:
在原始碼中我們能看到“GER.html”,這就意味著,只要得到搜尋的結果,我們可以分析HTML源碼來得到這個搜尋結果的串連網址,然後在該串連網址中擷取該國的國旗。所以,在這個爬蟲中,最困難的地方在於,如何擷取搜尋結果?即,得到提交表單後的結果,也就是POST方法提交後的響應結果。我們利用Fiddler來抓取該POST方法。
??我們開啟Fiddler, 同時重複上面的操作,可以得到該過程的HTTP請求,如:
Fiddler協助我們找到了剛才提交表單過程中的一個POST請求,具體分析該POST請求,其要求標頭部如下:
其請求體如下:
??為了驗證Fiddler抓取的POST請求,我們需要要Postman來進行測試。在用Postman進行測試前,我們需要問:是否所有要求標頭部中的資料都需要呢?答案是否定的,實際上,我們只需要User-Agent和Content-Type即可。在Postman中,先輸入要求標頭部,如下:
再輸入請求體,如下:
點擊"SEND"按鈕,得到響應後的結果,如下:
OK,這樣我們就完成了Postman的測試。
爬蟲
??於是,藉助這些資訊來完成request.post()的提交,同時,藉助BeautifulSoup來解析網頁,得到國家的國旗並完成下載。具體的Python代碼如下:
# -*- coding: utf-8 -*-import urllib.requestimport requestsfrom bs4 import BeautifulSoup# 函數:下載指定國家的國旗# 參數: country: 國家def download_flag(country): # 要求標頭部 headers = { ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36‘, ‘Content-Type‘: ‘application/x-www-form-urlencoded; charset=UTF-8‘, } # POST資料 data = {‘q‘: country} # 網址 url = ‘http://country.911cha.com/‘ # 提交POST請求 r = requests.post(url=url, data=data, headers=headers) # 利用BeautifulSoup解析網頁 content = BeautifulSoup(r.text, ‘lxml‘) # 得到搜尋結果(國家)所在網頁地址 country = content.find_all(‘div‘, class_=‘mcon‘)[1](‘ul‘)[0](‘li‘)[0](‘a‘)[0] link = country[‘href‘] #利用GET方法得到搜尋國家的網頁 r2 = requests.get(url=‘%s/%s‘%(url, link)) # 利用BeautifulSoup解析網頁 content = BeautifulSoup(r2.text, ‘lxml‘) # 擷取網頁中的圖片 images = content.find_all(‘img‘) # 擷取指定國家的國旗名稱及 for image in images: if ‘alt‘ in image.attrs: if ‘國旗‘ in image[‘alt‘]: name = image[‘alt‘].replace(‘國旗‘, ‘‘) link = image[‘src‘] # 下載國旗圖片 urllib.request.urlretrieve(‘%s/%s‘%(url, link), ‘E://flag/%s.gif‘%name)def main(): # countries.txt儲存各個國家的名稱 file = ‘E://flag/countries.txt‘ with open(file, ‘r‘) as f: counties = [_.strip() for _ in f.readlines()] # 遍曆各個國家,下載國旗 for country in counties: try: download_flag(country) print(‘%s國旗下載成功!‘%country) except: print(‘%s國旗下載失敗~‘%country)main()
其中countries.txt的部分內容如下:
運行上述Python代碼,我們發現在E盤的flag檔案夾下,已經下載了各個國家的國旗,如下:
這樣我們就完成了本次爬蟲的任務!
總結
??本次爬蟲利用Python的requests模組的POST方法,來類比網頁中的表單提交。為了得到表單提交過程中的HTTP請求,即要求標頭部和請求體,我們利用了抓包工具Fiddler,而Postman的作用是為了協助我們驗證Fiddler抓取的POST請求是否正是我們需要的POST請求,同時也能驗證要求標頭部及請求體。
??雖然整個爬蟲的過程寫的不免麻煩,但是操作的思路應該是清晰的,再說,熟能生巧,多用幾次,也就能熟悉整個流程了。本次爬蟲只是作為整個流程的一個簡單展示,讀者可以在此基礎上,去實現更為複雜的爬蟲,希望本次的分享能夠協助到讀者。謝謝大家能讀到這兒,也歡迎大家交流~~
注意:本人現已開通兩個公眾號: 因為Python(號為:python_math)以及輕鬆學會Python爬蟲(號為:easy_web_scrape), 歡迎大家關注哦~~
Python爬蟲之使用Fiddler+Postman+Python的requests模組爬取各國國旗