前面幾節,我們講述了操作html文件的相關知識,接下來我們就以猿人學首頁的內容提取為例,用例項展示lxml和xpath提取網頁資料的魅力。
目標 提取首頁文章的資訊,包括標題、作者、釋出時間、閱讀數、評論數、網址
PS:還沒了解 lxml和xpath的同學,先看下前面幾篇打底文章。
Python 爬蟲網頁解析工具lxml.html(一)
Python 爬蟲網頁解析工具lxml.html(二)
Python 爬蟲網頁內容提取工具xpath(一)
先研究一下猿人學首頁的結構
猿人學首頁的截圖如下:
結構簡潔清晰,對爬蟲很友好嘛,哈哈哈~~
左右結構,左側是主體部分,置頂了幾篇文章,下面的紅色框裡面的就是一篇篇文章的列表,也就是我們要提取的部分。
用Chrome開啟網頁,按F12調出網頁分析工具,可以看到文章列表在一個<ul>
下面,一個<li>
就是一篇文章的資料:
獲取網頁並生成lxml的文件節點
import requests
from lxml.html
headers = {'User-Agent': 'Firefox'}
resp = requests.get('https://www.yuanrenxue.com/', headers=headers)
html = resp.content.decode('utf8')
doc = lxml.html.fromstring(html)
驚天!猿人學竟然封鎖了requests的user-agent!!我不得不自定義header來繞過它的封鎖,哈哈哈~~~
這裡,我們自己解碼resp.content,而不是直接用的resp.text。對於utf8編碼的網頁,resp.text也是可以的,但是為什麼要自己解碼呢? 具體原因可以看看教程的另一篇文章:大規模非同步新聞爬蟲:實現一個更好的網路請求函式 關於cchardet模組的說明。
提取資料
首先,獲取文章列表的所有<li>
,根據前面我們研究得到的網頁結構,不難寫出對應的xpath:
In [241]: xp = '//ul[@id="postlist"]/li'
In [242]: lis = doc.xpath('//ul[@id="postlist"]/li')
In [243]: lis
Out[243]:
[<Element li at 0x7fc409fb68b8>,
<Element li at 0x7fc409fb6c78>,
<Element li at 0x7fc409fb6908>,
<Element li at 0x7fc40a0ebef8>,
<Element li at 0x7fc409fb7098>,
<Element li at 0x7fc40a260138>,
<Element li at 0x7fc40a2602c8>,
<Element li at 0x7fc40a260188>,
<Element li at 0x7fc40a2a5a98>,
<Element li at 0x7fc40a2a59f8>]
In [244]: len(lis)
Out[244]: 10
然後,解析<li>
,提取單篇文章的要素,同樣在瀏覽器檢視一下<li>
的結構:
結構清晰明朗,提取起來毫無壓力,猿人學真是爬蟲友好的好網站啊,哈哈哈~
下面我就看著網頁結構來寫提取要素的函式:
def parse(li):
item = {}
# class="thumb"的div有兩個<a>,第一個是類別連結,第二個是文章連結
thumb = li.xpath('./div[@class="thumb"]/a')
item['cat'] = thumb[0].text
item['link'] = thumb[1].get('href')
# 獲取title
el_title = li.xpath('.//h2[@class="info-tit"]/a')[0]
item['title'] = el_title.text
el_info = li.xpath('.//div[@class="info-item"]/span')
for span in el_info:
attr = span.get('class')
if attr == 'author':
item['author'] = span.text_content()
elif attr == 'time':
item['time'] = span.text_content()
elif attr == 'view':
digit = re.findall(r'\d+', span.text_content())[0]
item['view_count'] = int(digit)
elif attr == 'cmt':
digit = re.findall(r'\d+', span.text_content())[0]
item['cmt_count'] = int(digit)
return item
以上,我們就完整的提取出了猿人學首頁顯示的最新10篇文章的資料。上面程式碼片段的完整程式碼可以到本教程的github檢視、下載。
執行一下完整程式碼,並列印出提出的第一篇文章的詳細資訊,可以看到輸出結果:
lis: 10
articles: 10
{'author': '王平',
'cat': 'python爬蟲教程',
'cmt_count': 0,
'link': 'https://www.yuanrenxue.com/crawler/crawler-tricks-2.html',
'time': '\ue60419小時前',
'title': '網路爬蟲小偏方:修改referer繞開登入和訪問頻率限制',
'view_count': 505}
知識點
- 如果剛一開始對xpath不太熟悉,可以藉助Chrome的F12檢視元素來獲得XPath,右鍵點選想要獲取的節點,選擇選單即可:
我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。
***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***