進一步了解XPath(利用XPath爬取飛哥的博客)【python爬蟲入門進階】(04)
您好,我是碼農飛哥,感謝您閱讀本文,歡迎一鍵三連哦。
本文是爬蟲專欄的第四篇,重點介紹lxml庫與XPath搭配使用解析網頁提取網頁內容。
干貨滿滿,建議,系列文章持續更新。 小伙伴們如有問題及需要,歡迎踴躍留言告訴我哦~ ~ ~。
前言(為什么寫這篇文章)
上一篇文章我們簡單的介紹了Html與xml的基本概念,并且重點介紹了XPath的語法。這篇文章就讓我們來實戰一下: 通過本文你將學會如何 如何利用lxml庫來加載和解析網頁,然后搭配XPath的語法定位特定元素及節點信息的知識點。
@[toc]
lxml庫的介紹
lxml庫是一個HTML/XML的解析器,主要功能是如何解析和提取HTML/XML的數據。
lxml和正則一樣,也是用C語言實現的,是一款高性能的Python HTML/XML解析器。利用前面學習的XPath的語法來快速定位網頁上的特定元素以及節點信息。
利用pip安裝lxm庫
pip install lxml
利用lxml庫解析HTML片段
lxml庫可以解析傳入的任何一段XML或者HTML片段,當然前提是你的XML或者HTML片段沒有語法錯誤。
#lxml_test.py from lxml import etree text = """
全網ID名:碼農飛哥
掃碼加入技術交流群!

從上面的輸出結果可以看出etree.HTML(text) 方法可以將字符串解析成HTML文檔,也就是一個Element對象。etree.tostring(html) 可以將HTML文檔序列化成字符串,序列化之后的結果是一個 bytes 對象,中文是不能正常顯示的。需要通過指定編碼方式為utf-8,并且調用decode()方法中文才能正常輸出,并且輸出的HTML是有格式的。即不是打印成一行。
利用lxml庫加載html文件
lxml庫不僅僅可以解析XML/HTML片段,還可以解析完整的HTML/XML文件 。下面創建了一個名為test.html文件。然后通過 etree.parse方法進行解析。
全網ID名:碼農飛哥
掃碼加入技術交流群!

然后創建一個html_parse.py的文件進行解析,需要注意的是該文件跟test.html文件在同一個目錄下。
# html_parse.py from lxml import etree #讀取外部文件 test.html html = etree.parse('./test.html') result = etree.tostring(html, encoding='utf-8').decode() print(result)
解析結果是:
可以看出如果被解析的HTML文件是一個標準的HTML代碼片段的話則可以正常加載,因為這里parse方法默認使用的是XML的解析器。
但是當HTML文件是一個標準的完整的HTML文件則XML解析器是不能解析。現在將test.html 改下圖2的代碼,如果直接使用XML解析器解析就會報下面的錯誤。
針對HTML文件需要通過HTMLParser方法設置HTML解析器。然后在parse方法指定該解析器,就像下面代碼所示的一樣。
from lxml import etree # 定義解析器 html_parser = etree.HTMLParser(encoding='utf-8') # 讀取外部文件 test.html html = etree.parse('./test.html', parser=html_parser) result = etree.tostring(html, encoding='utf-8').decode() print(result)
運行結果是:
實戰開始
了解了lxml方法的基本使用之后,接下來我們就以碼農飛哥的博客 為例。這里我們的需求是爬取他博客下所有文章(暫不包括文章內容),然后將爬取的數據保存到本地txt文件中。首先讓我們來看看他的博客長啥樣。涉及前面幾篇博客知識點這里不再詳細介紹了。這里重點介紹如何通過XPath來快速定位特定的元素和數據。
第一步: 獲得文章的分組
首先獲取文章的分組,還是使用萬能的XPath Helper, 通過F12調出調試窗口,可以看出每個文章分組都是放在
。所以,通過 //div[@class="article-item-box csdn-tracking-statistics"] 表達式就可以獲取所有的文章分組。代碼示例如下:
from lxml import etree import requests response = requests.get("https://feige.blog.csdn.net/", timeout=10) # 發送請求 html = response.content.decode() html = etree.HTML(html) # 獲取文章分組 li_temp_list = html.xpath('//div[@class="article-item-box csdn-tracking-statistics"]') print(li_temp_list)
運行結果是:
這里通過html.xpath('//div[@class="article-item-box csdn-tracking-statistics"]') 方法得到40個Element對象。這40個Element對象就是我們需要爬取的當前頁面的所有文章。 每個Element對象就是下面這樣的內容。
接下來通過result = etree.tostring(li_temp_list[0], encoding='utf-8').decode() 方法序列化Element對象,得到的結果是:
第二步: 獲取文章的鏈接