在使用Python本爬蟲採集資料時,一個很重要的操作就是如何從請求到的網頁中提取資料,而正確定位想要的資料又是第一步操作。
本文將比較幾種Python 爬蟲中比較常用的定位網頁元素的方式供大家學習
“」
傳統 BeautifulSoup
操作基於 BeautifulSoup
的CSS 選擇器(與PyQuery
類似)XPath
正規表示式
參考網頁是當網圖書暢銷總榜:
http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1
我們以取得第一頁 20 本書的書名為範例。先確定網站沒有設定反爬措施,是否能直接回傳待解析的內容:
import requests url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1' response = requests.get(url).text print(response)
#仔細檢查後發現需要的資料都在回傳內容中,說明不需要特別考慮反爬舉措
審查網頁元素後可以發現,書目資訊都包含在li
中,從屬於class
為bang_list clearfix bang_list_mode
的ul
中
進一步檢視也可以發現書名在的對應位置,這是多種解析方法的重要基礎
經典的BeautifulSoup 方法借助from bs4 import BeautifulSoup
,然後透過soup = BeautifulSoup(html, "Soup(html, "Soup
# lxml")將文字轉換為特定規範的結構,利用
find
import requests from bs4 import BeautifulSoup url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1' response = requests.get(url).text def bs_for_parse(response): soup = BeautifulSoup(response, "lxml") li_list = soup.find('ul', class_='bang_list clearfix bang_list_mode').find_all('li') # 锁定ul后获取20个li for li in li_list: title = li.find('div', class_='name').find('a')['title'] # 逐个解析获取书名 print(title) if __name__ == '__main__': bs_for_parse(response)
这种方法实际上就是 PyQuery 中 CSS 选择器在其他模块的迁移使用,用法是类似的。关于 CSS 选择器详细语法可以参考:http://www.w3school.com.cn/cssref/css_selectors.asp
由于是基于 BeautifulSoup 所以导入的模块以及文本结构转换都是一致的:
import requests from bs4 import BeautifulSoup url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1' response = requests.get(url).text def css_for_parse(response): soup = BeautifulSoup(response, "lxml") print(soup) if __name__ == '__main__': css_for_parse(response)
然后就是通过soup.select
辅以特定的 CSS 语法获取特定内容,基础依旧是对元素的认真审查分析:
import requests from bs4 import BeautifulSoup from lxml import html url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1' response = requests.get(url).text def css_for_parse(response): soup = BeautifulSoup(response, "lxml") li_list = soup.select('ul.bang_list.clearfix.bang_list_mode > li') for li in li_list: title = li.select('div.name > a')[0]['title'] print(title) if __name__ == '__main__': css_for_parse(response)
XPath 即为 XML 路径语言,它是一种用来确定 XML 文档中某部分位置的计算机语言,如果使用 Chrome 浏览器建议安装XPath Helper
插件,会大大提高写 XPath 的效率。
之前的爬虫文章基本都是基于 XPath,大家相对比较熟悉因此代码直接给出:
import requests from lxml import html url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1' response = requests.get(url).text def xpath_for_parse(response): selector = html.fromstring(response) books = selector.xpath("//ul[@class='bang_list clearfix bang_list_mode']/li") for book in books: title = book.xpath('div[@class="name"]/a/@title')[0] print(title) if __name__ == '__main__': xpath_for_parse(response)
如果对 HTML 语言不熟悉,那么之前的几种解析方法都会比较吃力。这里也提供一种万能解析大法:正则表达式,只需要关注文本本身有什么特殊构造文法,即可用特定规则获取相应内容。依赖的模块是re
首先重新观察直接返回的内容中,需要的文字前后有什么特殊:
import requests import re url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1' response = requests.get(url).text print(response)
观察几个数目相信就有答案了: