Python 爬蟲網頁內容提取工具xpath(二)

王平發表於2018-12-08

前面幾節,我們講述了操作html文件的相關知識,接下來我們就以猿人學首頁的內容提取為例,用例項展示lxml和xpath提取網頁資料的魅力。

目標 提取首頁文章的資訊,包括標題、作者、釋出時間、閱讀數、評論數、網址

PS:還沒了解 lxml和xpath的同學,先看下前面幾篇打底文章。
Python 爬蟲網頁解析工具lxml.html(一)
Python 爬蟲網頁解析工具lxml.html(二)
Python 爬蟲網頁內容提取工具xpath(一)

先研究一下猿人學首頁的結構

猿人學首頁的截圖如下:

猿人學首頁截圖

結構簡潔清晰,對爬蟲很友好嘛,哈哈哈~~
左右結構,左側是主體部分,置頂了幾篇文章,下面的紅色框裡面的就是一篇篇文章的列表,也就是我們要提取的部分。
用Chrome開啟網頁,按F12調出網頁分析工具,可以看到文章列表在一個<ul>下面,一個<li>就是一篇文章的資料:

猿人學首頁文章列表html

獲取網頁並生成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}

知識點

  1. 如果剛一開始對xpath不太熟悉,可以藉助Chrome的F12檢視元素來獲得XPath,右鍵點選想要獲取的節點,選擇選單即可:

Chrome獲取XPath

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章