對於大多數朋友而言,爬蟲絕對是學習 python 的最好的起手和入門方式。因為爬蟲思維模式固定,編程模式也相對簡單,一般在細節處理上積累一些經驗都可以成功入門。本文想針對某一網頁對 python 基礎爬蟲的兩大解析庫( BeautifulSoup 和 lxml )和幾種信息提取實現方法進行分析,以開 ...
對於大多數朋友而言,爬蟲絕對是學習 python
的最好的起手和入門方式。因為爬蟲思維模式固定,編程模式也相對簡單,一般在細節處理上積累一些經驗都可以成功入門。本文想針對某一網頁對 python
基礎爬蟲的兩大解析庫( BeautifulSoup
和 lxml
)和幾種信息提取實現方法進行分析,以開 python
爬蟲之初見。
基礎爬蟲的固定模式
筆者這裡所談的基礎爬蟲,指的是不需要處理像非同步載入、驗證碼、代理等高階爬蟲技術的爬蟲方法。一般而言,基礎爬蟲的兩大請求庫 urllib
和 requests
中 requests
通常為大多數人所鐘愛,當然 urllib
也功能齊全。兩大解析庫 BeautifulSoup
因其強大的 HTML
文檔解析功能而備受青睞,另一款解析庫 lxml
在搭配 xpath
表達式的基礎上也效率提高。就基礎爬蟲來說,兩大請求庫和兩大解析庫的組合方式可以依個人偏好來選擇。
筆者喜歡用的爬蟲組合工具是:
-
requests
+BeautifulSoup
-
requests
+lxml
同一網頁爬蟲的四種實現方式
筆者以騰訊新聞首頁的新聞信息抓取為例。
首頁外觀如下:
比如說我們想抓取每個新聞的標題和鏈接,並將其組合為一個字典的結構列印出來。首先查看 HTML
源碼確定新聞標題信息組織形式。
可以目標信息存在於 em
標簽下 a
標簽內的文本和 href
屬性中。可直接利用 requests
庫構造請求,並用 BeautifulSoup
或者 lxml
進行解析。
-
方式一:
requests
+BeautifulSoup
+select
css選擇器
1 # select method 2 import requests 3 from bs4 import BeautifulSoup 4 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'} 5 6 url = 'http://news.qq.com/' 7 8 Soup = BeautifulSoup(requests.get(url=url, headers=headers).text.encode("utf-8"), 'lxml') 9 10 em = Soup.select('em[class="f14 l24"] a') 11 for i in em: 12 13 title = i.get_text() 14 15 link = i['href'] 16 17 print({'標題': title, 18 '鏈接': link 19 20 })
很常規的處理方式,抓取效果如下:
-
方式二:
requests
+BeautifulSoup
+find_all
進行信息提取
1 # find_all method 2 import requests 3 from bs4 import BeautifulSoup 4 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'} 5 6 url = 'http://news.qq.com/' 7 8 Soup = BeautifulSoup(requests.get(url=url, headers=headers).text.encode("utf-8"), 'lxml') 9 10 em = Soup.find_all('em', attrs={'class': 'f14 l24'})for i in em: 11 12 title = i.a.get_text() 13 14 link = i.a['href'] 15 16 print({'標題': title, 17 '鏈接': link 18 19 })
同樣是 requests
+ BeautifulSoup
的爬蟲組合,但在信息提取上採用了 find_all
的方式。效果如下:
-
方式三:
requests
+lxml/etree
+xpath
表達式
1 # lxml/etree method 2 import requests 3 from lxml import etree 4 5 6 7 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'} 8 9 url = 'http://news.qq.com/' 10 11 html = requests.get(url = url, headers = headers) 12 13 con = etree.HTML(html.text) 14 15 16 17 title = con.xpath('//em[@class="f14 l24"]/a/text()') 18 19 link = con.xpath('//em[@class="f14 l24"]/a/@href') 20 for i in zip(title, link): 21 22 print({'標題': i[0], 23 '鏈接': i[1] 24 25 })
使用 lxml
庫下的 etree
模塊進行解析,然後使用 xpath
表達式進行信息提取,效率要略高於 BeautifulSoup
+ select
方法。這裡對兩個列表的組合採用了 zip
方法。python學習交流群:125240963效果如下:
-
方式四:
requests
+lxml/html/fromstring
+xpath
表達式
1 # lxml/html/fromstring method 2 import requests 3 import lxml.html as HTML 4 5 6 7 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'} 8 9 url = 'http://news.qq.com/' 10 11 con = HTML.fromstring(requests.get(url = url, headers = headers).text) 12 13 title = con.xpath('//em[@class="f14 l24"]/a/text()') 14 15 link = con.xpath('//em[@class="f14 l24"]/a/@href') 16 for i in zip(title, link): 17 18 print({'標題': i[0],'鏈接': i[1] 19 20 })
跟方法三類似,只是在解析上使用了 lxml
庫下的 html.fromstring
模塊。抓取效果如下:
很多人覺得爬蟲有點難以掌握,因為知識點太多,需要懂前端、需要python熟練、還需要懂資料庫,更不用說正則表達式、XPath表達式這些。其實對於一個簡單網頁的數據抓取,不妨多嘗試幾種抓取方案,舉一反三,也更能對python爬蟲有較深的理解。長此以往,對於各類網頁結構都有所涉獵,自然經驗豐富,水到渠成。