Python应用实战- 爬虫基础入门知识必会
0.爬蟲基礎流程
把爬蟲的過程模塊化,基本上可以歸納為以下幾個步驟:
-
[√] 分析網頁URL:打開你想要爬取數據的網站,然后尋找真實的頁面數據URL地址;
-
[√] 請求網頁數據:模擬請求網頁數據,這里我們介紹requests庫的使用;
-
[√] 解析網頁數據:根據請求獲得的網頁數據我們用不同的方式解析成我們需要用的數據(如果網頁數據為html源碼,我們用Beautiful Soup、xpath和re正則表達式三種解析;若網頁數據為json格式,我們可以直接用字典列表等基礎知識處理)
-
[√] 存儲網頁數據:一般來說,解析后的數據是比較結構化的,可以保存為txt、csv、json或excel等文本,亦或者可以存儲在數據庫如MySql、MongoDB或SqlLite中。
1.分析網頁URL
當我們有一個目標網站,有時候會發現對于靜態網頁,我們只需要把網頁地址欄中的URL傳到get請求中就可以直接取到網頁的數據。但如果這是動態網頁,我們便無法通過簡單的傳遞網頁地址欄的URL給get請求來獲取網頁數據,往往這個時候,我們進行翻頁的時候還會發現網頁地址欄中的URL是不會發生變化的。
接下來,我們來分別介紹這兩種情況下如何獲取真實的頁面數據URL地址。
1.1 靜態網頁
對于靜態網頁來說,其實網頁地址欄中的URL就是我們需要的。
以?貝殼二手房網(https://bj.ke.com/ershoufang/) 為例,我們可以看到進行翻頁(如到第2頁)的時候網頁地址欄的URL變為了(https://bj.ke.com/ershoufang/pg2/)。類型這種情況,多半就是靜態網頁了,而且翻頁的URL規律十分明顯。
1.2 動態網頁
對于動態網頁來說,我們一般可以通過以下幾個步驟找到真實URL地址:
需要按“F12”進入到瀏覽器的開發者模式;
點擊“Network”—>XHR或JS或者你全部查找看;
進行翻頁(可能是點擊下一頁或者下滑加載更多);
觀察第2步中name模塊的內容變化,尋找。
以?虎牙星秀區(https://www.huya.com/g/xingxiu) 為例,我們可以看到進行翻頁(如到第2頁)的時候網頁地址欄的URL沒有發生任何改變。
為了便于找到真實的URL地址,我們可以在開發者模式中找以下截圖中的幾點,preview是預覽結果,可以便于我們進行匹配定位具體的Name。
虎牙星秀區
當我們定位到具體的Name后,右側選擇Headers可以查看到請求網頁需要的相關參數信息,而且比較好擬清其變化規律。以虎牙星秀為例,其真實URL地址及變化規律如下:
URL= 'https://www.huya.com/cache.php?m=LiveList&do=getLiveListByPage&gameId=1663&tagAll=0&page=2'
基礎 url 地址如下:
url?=?'https://www.huya.com/cache.php’請求參數parames如下:
parames?=?{'m':?'LiveList','do':?'getLiveListByPage','gameId':?1663,'tagAll':?0,'page':?2,?#?翻頁變化的就是這個參數}真實URL地址
2.請求網頁數據
當我們確定了真實數據的URL后,這里便可以用requests的get或post方法進行請求網頁數據。
關于requests庫的更多使用方式,大家可以前往(https://requests.readthedocs.io/zh_CN/latest/)查看。
2.1 發送get請求
In?[1]:?import?requestsIn?[2]:?url?=?'https://bj.ke.com/ershoufang/'In?[3]:?r?=?requests.get(url)In?[4]:?type(r) Out[4]:?requests.models.ResponseIn?[5]:?r.status_code Out[5]:?200我們得到的是一個Response對象,如果我們想要獲取網頁數據,可以使用text或content屬性來獲取,另外如果獲取的網頁數據是json格式的則可以使用Requests 中內置的 **json()**解碼器方法,助你處理json 數據。
-
r.text:字符串類型的數據,一般網頁數據為文本類用此屬性
-
r.content:二進制類型的數據,一般網頁數據為視頻或者圖片時用此屬性
-
r.json():json數據解碼,一般網頁數據為json格式時用此方法
對于一些動態網頁,請求的網址是基礎url和關鍵字參數組合而成,這個時候我們可以使用?params?關鍵字參數,以一個字符串字典來提供這些參數。
In?[6]:?url?=?'https://www.huya.com/cache.php'...:?parames?=?{...:?????'m':?'LiveList',...:?????'do':?'getLiveListByPage',...:?????'gameId':?1663,...:?????'tagAll':?0,...:?????'page':?2,?#?翻頁變化的就是這個參數...:?????}...:?...:?r?=?requests.get(url,?params=parames)In?[7]:?r.url Out[7]:?'https://www.huya.com/cache.php?m=LiveList&do=getLiveListByPage&gameId=1663&tagAll=0&page=2'2.2 發送post請求
通常,你想要發送一些編碼為表單形式的數據——非常像一個 HTML 表單。要實現這個,只需簡單地傳遞一個字典給 data 參數。你的數據字典在發出請求時會自動編碼為表單形式:
>>>?payload?=?{'key1':?'value1',?'key2':?'value2'}>>>?r?=?requests.post("http://httpbin.org/post",?data=payload)很多時候你想要發送的數據并非編碼為表單形式的。如果你傳遞一個?string?而不是一個?dict,那么數據會被直接發布出去。
>>>?import?json>>>?url?=?'https://api.github.com/some/endpoint' >>>?payload?=?{'some':?'data'}>>>?r?=?requests.post(url,?data=json.dumps(payload))此處除了可以自行對?dict?進行編碼,你還可以使用?json?參數直接傳遞,然后它就會被自動編碼。
>>>?url?=?'https://api.github.com/some/endpoint' >>>?payload?=?{'some':?'data'}>>>?r?=?requests.post(url,?json=payload)2.3 定制請求頭
在模擬請求時,如果不設置請求頭的話是比較容易被網站發現是來自爬蟲腳本,一些網站會對這種模擬請求進行拒絕。因此我們可以簡單設置一下請求頭做偽裝,一般是設置瀏覽器。
headers?=?{"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/87.0.4280.66?Safari/537.36",} r?=?requests.get(url,?headers=headers)其實,對于請求頭還可以設置很多參數,具體大家可以在實際爬蟲過程中在開發者模式看看里面的請求頭模塊進行分析處理。
虎牙星秀請求頭
2.4 響應碼
我們在 2.1 中看到獲取響應碼的是通過?r.status_code屬性,一般來說如果 返回 數字?200,則表示成功獲取了網頁數據。
響應碼分為五種類型,由它們的第一位數字表示:1xx:信息,請求收到,繼續處理 2xx:成功,行為被成功地接受、理解和采納 3xx:重定向,為了完成請求,必須進一步執行的動作 4xx:客戶端錯誤,請求包含語法錯誤或者請求無法實現 5xx:服務器錯誤,服務器不能實現一種明顯無效的請求
3.解析數據
上面有提到我們請求的網頁數據有Html源碼文本或者是json字符串文本,兩者的解析方式不同。以下我們分別進行簡單說明,大家在實際操作中視情況而定即可。
3.1 網頁html文本解析
對于網頁html文本來說,這里介紹Beautiful Soup、xpath和re正則表達式三種解析方法。
以貝殼二手房最新房源(https://bj.ke.com/ershoufang/co32/)為例,其html源碼如下,我們通過get請求后的數據進行解析。
貝殼二手房
3.1.1 Beautiful Soup
關于Beautiful Soup庫的更多使用方式,大家可以前往查看(https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/)
首先安裝pip install beautifulsoup4。
我們將網頁html文本內容r.text當作第一個參數傳給BeautifulSoup對象,該對象的第二個參數為解析器的類型(這里使用lxml),此時就完成了BeaufulSoup對象的初始化。然后,將這個對象賦值給soup變量。
from?bs4?import?BeautifulSoup import?requestsurl?=?'https://bj.ke.com/ershoufang/co32/' r?=?requests.get(url) soup?=?BeautifulSoup(r.text,?'lxml')房源名稱
獲取房源的名稱的代碼如下:
#?獲取全部房源?所在的節點 sellList?=?soup.find(class_="sellListContent") #?獲取全部房源節點列表 lis?=?sellList.find_all('li',class_="clear") #?選取第一個房源節點 div?=?lis[0].find('div',class_="info?clear") #?采集房源名稱 title?=?div.find('div',class_="title") print(title.text) 明春西園?2室1廳?南?北房源其他信息大家可以自己處理,強化學習!
3.1.2 xpath
XPath,全稱 XML Path Language,即 XML 路徑語言,它是一門在 XML 文檔中查找信息的語言。
首先安裝lxmlpip install lxml。
常見的規則如下:
| nodename | 選取此節點的所有子節點 |
| / | 從當前節點選取直接子節點 |
| // | 從當前節點選取子孫節點 |
| . | 選取當前節點 |
| .. | 選取當前節點的父節點 |
| @ | 選取屬性 |
首先導入 lxml 庫的 etree 模塊,然后聲明一段 HTML 文本,調用 HTML 類進行初始化,成功構造一個 XPath 解析對象。
from?lxml?import?etree import?requestsurl?=?'https://bj.ke.com/ershoufang/co32/' r?=?requests.get(url) html?=?etree.HTML(r.text)右鍵可獲取xpath
通過copy獲取的xpath://*[@id="beike"]/div[1]/div[4]/div[1]/div[4]/ul/li[1]/div/div[1]/a
#?獲取?全部房源所在節點?ul,根據屬性匹配精準查找 ul?=?html.xpath('.//ul[@class="sellListContent"]')[0] #?獲取房源列表 lis?=?ul.xpath('.//li[@class="clear"]') #?選取第一個房源節點 li?=?lis[0] #?獲取其房源名稱 li.xpath('./div/div[1]/a/text()') ['明春西園?2室1廳?南?北']其他房源信息,大家可以自行處理,強化學習!
3.1.3 re正則
關于re正則解析網頁html大家也可以前往查看此前發布的文章《對著爬蟲網頁HTML學習Python正則表達式re》。
#?找到房源名稱所在的前后字符,然后組成正則表達式 re.findall(r'<a?class="VIEWDATA?CLICKDATA?maidian-detail"?title="(.*?)"',r.text,re.S)[0] '明春西園?2室1廳?南?北'3.2 json文本解析
在requests提供了r.json(),可以用于json數據解碼,一般網頁數據為json格式時用此方法。除此之外,還可以通過json.loads()和eval()方法進行處理,具體可以參考此前文章《Python爬取美團網數據這么簡單,別再說你不會了哦!》。
json文本解析
url?=?'https://www.huya.com/cache.php' parames?=?{'m':?'LiveList','do':?'getLiveListByPage','gameId':?1663,'tagAll':?0,'page':?2,?#?翻頁變化的就是這個參數}r?=?requests.get(url,?params=parames) data?=?r.json() type(data) dict如此解析后得到的數據就是字典,然后我們在看看字典中哪些字段是我們需要的,取出即可。
4.存儲數據
當我們獲取了到想要的數據后,便可以寫入本地了。
對于文本類數據,可以通過csv模塊或pandas模塊進行寫入到本地csv文件或excel文件;同時也可以用pymysql模塊寫入到數據庫或者sqlite寫入到本地數據庫。
對于視頻或者圖片,可以open一個文件然后寫入二進制內容后保存本地亦可。
關于存儲數據大家可以結合實際案例進行學習。
總結
以上是生活随笔為你收集整理的Python应用实战- 爬虫基础入门知识必会的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Panda处理文本和时序数据?首选向量化
- 下一篇: Python办公自动化,对文件进行自由操