在使用Python本爬虫采集数据时,一个很重要的操作就是如何从请求到的网页中提取数据 ,而正确定位想要的数据又是第一步操作。
本文将对比几种 Python 爬虫中比较常用的定位网页元素 的方式供大家学习
“ 基于 BeautifulSoup
的 CSS 选择器(与 PyQuery
类似) ” 参考网页是当当网图书畅销总榜 :
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
中
进一步审查也可以发现书名在的相应位置,这是多种解析方法的重要基础
1. 传统 BeautifulSoup 操作 经典的 BeautifulSoup 方法借助 from bs4 import BeautifulSoup
,然后通过 soup = BeautifulSoup(html, "lxml")
将文本转换为特定规范的结构,利用 find
系列方法进行解析,代码如下:
import requestsfrom 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).textdef 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)
成功获取了 20 个书名,有些书面显得冗长可以通过正则或者其他字符串方法处理,本文不作详细介绍
2. 基于 BeautifulSoup 的 CSS 选择器 这种方法实际上就是 PyQuery 中 CSS 选择器在其他模块的迁移使用,用法是类似的。关于 CSS 选择器详细语法可以参考:http://www.w3school.com.cn/cssref/css_selectors.asp
由于是基于 BeautifulSoup 所以导入的模块以及文本结构转换都是一致的:
import requestsfrom 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 requestsfrom bs4 import BeautifulSoupfrom 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)
3. XPath XPath 即为 XML 路径语言,它是一种用来确定 XML 文档中某部分位置的计算机语言,如果使用 Chrome 浏览器建议安装 XPath Helper
插件,会大大提高写 XPath 的效率。
之前的爬虫文章基本都是基于 XPath,大家相对比较熟悉因此代码直接给出:
import
requestsfrom 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).textdef 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)
4. 正则表达式 如果对 HTML 语言不熟悉,那么之前的几种解析方法都会比较吃力。这里也提供一种万能解析大法:正则表达式 ,只需要关注文本本身有什么特殊构造文法,即可用特定规则获取相应内容。依赖的模块是 re
首先重新观察直接返回的内容中,需要的文字前后有什么特殊:
import requestsimport 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)
观察几个数目相信就有答案了:
前往“发现”-“看一看”浏览“朋友在看”