爬虫处理流程:
- 将互联网上的网页获取到本地
- 对网页进行解析
网页解析是从网页中分离出我们所需要的、有价值的信息,以及新的待爬取的URL。
网页的解析的方法:- 正则表达式(采用模糊匹配的方式,找出我们所需要内容)
- BeautifulSoup(是一个可以从HTML或XML文件中提取数据的第三方Python库), BeautifulSoup可以采用Python自带的
html.parse
作为它的解析器,也可以采用lxml
作为解析器。
lxml 是Python语言解析处得XML和HTML的库
- XPath(XPath 是一门在 XML 文档中查找信息的语言,XPath 可用来在 XML 文档中对元素和属性进行遍历。)
- 对解析出来的数据进行处理。
一、使用BeautifulSoup
安装:
pip install beautifulsoup4
安装lxml:
pip install lxml
解析器 | 使用方法 | 优点 | 缺点 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, “html.parser”) | Python的内置标准库,执行速度适中,文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, “lxml”) | 速度快,文档容错能力强 | 需要安装C语言库 |
- 首先必须要导入 bs4 库,创建BeautifulSoup对象
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml') #html为下载的网页,lxml为解析器
- 详细使用可以看Beautiful Soup 4.2.0 文档
掌握以下三个方法基本够用:
- find_all("tag") 搜索当前所有的tag标签的集合。
- find("tag") 返回的是一个tag标签。(这个方法用得少)
- select("") 可以按标签名查找,用得多的是按标签逐层查找筛选元素。
二、使用BeautifulSoup提取网页内容的一些技巧
1、find_all()方法中放单独的标签名,如a
,会提取网页中所有的a
标签,这里要确保是我们所需要的链接a
,一般都不是,需要加上条件(就是标签的属性,加以限制筛选),如果这一级标签没有属性,最好往上一级找。
以糗事百科为例来说明,http://www.qiushibaike.com/text/
,抓取原创笑话段子。
发现内容都在span
标签中,如果写 find_all("span")
可以抓取到段子的内容,但是还包含了网页上其他span
的内容。这时我们往上一级标签上看,<div class="content>
就是只包含了段子内容的标签。
# coding=utf-8
import requests
from bs4 import BeautifulSoup
html = requests.get('http://www.qiushibaike.com/text/').content
soup = BeautifulSoup(html,'lxml')
links = soup.find_all('div',class_='content')
for link in links:
print link.span.get_text()
取出来的link的内容就是div
,我们取它的span
中的内容就是我们需要段子的内容。
2、select() 方法,可以按标签逐层查找到我们所需要的内容,这点特点方便,就是定位,避免了单一的标签无法定位到我们所需要的内容元素。
soup.select("html head title") ##标签层级查找
soup.select('td div a') ## 标签路径 td --> div --> a
soup.select('td > div > a')
注意,以上按路径 标签之间的空格 td div a,可以用>,但也要注意>与标签之间都有空格。推荐使用 > 的方式。
我们使用Chrome浏览器,右键copy - selector (鼠标要放在标签上)
注意得到的内容,是从
#
开始的,这是上面div
的id
(#
表示的是id
),如果按此去搜索标签内容,只能得到一条内容。
#qiushi_tag_118962045 > a > div > span
需要改一下,按照个标签顺序去匹配搜索内容。这里第一个div
就是 有id数字的那个div
div > a > div > span
按这个路径去搜索时,发现还匹配到评论的内容,这就是定位的问题,需要改得更准确一些。
a.contentHerf > div > span
改为从a
标签开始,并且加上它的class
属性。a.contentHerf
是<a class="contentHerf"
在select()方法中的写法。
# coding=utf-8
import requests
from bs4 import BeautifulSoup
html = requests.get('http://www.qiushibaike.com/text/').content
soup = BeautifulSoup(html,'lxml')
links = soup.select('a.contentHerf > div > span')
for link in links:
print link.get_text()
#print link.text 这样写可以
两种方式抓取到糗百的段子。注意这里只抓取了一页的内容。
PS 可以参见之前的内容:使用Beautiful Soup抓取结构化数据