分析网页
在构建网络爬虫时,我们需要跟踪网络链接的方式下载我们所需要的网页。然后从每个网页中提取我们需要的一些数据,然后实现某些事情,这种做法叫抓取。
首先,我们需要分析网页结构,推荐使用firebug。常用的抽取网页内容的方法主要有三种,分别是正则表达式、Beautiful Soup和lxml。
三种方法比较:
抓取方法 | 性能 | 使用难度 | 安装难度 |
---|---|---|---|
正则表达式(推荐) | 快 | 困难 | 简单(内置模块) |
Beautiful Soup | 慢 | 简单 | 简单(纯Python) |
Lxml(更推荐) | 快 | 简单 | 相对困难 |
一、 正则表达式
配合re模块一起使用,如下:
import re
import requests
html = requests.get(url).content
re.findall('<td class="class">(.*?)</td>',html)
二、 Beautiful Soup
Beautiful Soup 是一个非常流行的python模块。该模块可以解析网页,并提供定位内容的便捷接口。可通过以下命令安装
pip install Beautifulsoup4
使用Beautiful Soup的第一步是将已下载的HTML内容解析为soup文档由于大多网页都不具备HTML格式,因此,Beautiful Soup需要对其实际格式进行确定。Beautiful Soup能够正确解析缺失的引号并闭合标签,此外和可以给HTML文档添加和标签使其成为完整的HTML文档,然后通过find()和find_all()方法来定位需要的元素。
例2.1:
from bs4 import BeautifulSoup
broken_html = '<ul class=country><li>Area<li>Population</ul>'
soup = BeautifulSoup(broken_html, 'html.parser')
print(soup.prettify())
输出2.1:
<ul class="country">
<li>
Area
<li>
Population
</li>
</li>
</ul>
例2.2(接上):
ul = soup.find('ul',attrs ={'class':'country'})
li = ul.find('li') #返回第一个'li'标签
li_list = ul.find_all('li') #以数组形式返回所有查询的'li'标签
li_text = ul.find('li').text #返回'li'标签的内容
print li
输出2.2:
<li>Area <li>Population</li></li>
以上补全代码方法与书上演示代码略有不同,可能是使用Python版本不同造成的。
三、Lxml
Lxml是基于libxml2这一XML解析库的Python的Python封装。该模块使用C语言编写,解析速度比Beautiful Soup快得多,不过安装过程也更加复杂。和Beautiful Soup一样,使用xml模块的第一步也是将有可能不合法的HTML解析为统一格式。
例3.1:
import lxml.html
broken_html = '<ul class=country><li>Area<li>Population</ul>'
tree = lxml.html.fromstring(broken_html)
fixed_html = lxml.html.tostring(tree,pretty_print=True)
print fixed_html
输出3.1:
<ul class="country">
<li>Area</li>
<li>Population</li>
</ul>
同样的,lxml也可以正确解析属性两侧缺失的引号,并闭合标签。而且该模块与演示模块结果相同,所以更推荐该模块。
解析完内容之后,进入选择元素的步骤。lxml有几种不同的方法:XPath,类似Beautiful Soup的find()方法、CSS选择器。此处仅介绍CSS选择器,因为他更简洁(需要了解基础CSS语法),并且可在动态中使用。但是CSS选择器需要重新单独安装,略微复杂。
实例3.2
待定
CSS选择器
CSS选择器表示选择元素所使用的模式,下面是一些选择器的示例:
选择所有标签:*
选择<a>标签:a
选择所有class="link"的元素:.link
选择class="link"的<a>标签:a.link
选择ip="home"的<a>标签:a#home
选择父元素为<a>标签的所有<span>字标签:a > span
选择<a>标签内部的所有<span>标签:a span
选择title属性为"Home"的所有的<a>标签:a[title=Home]
参考书目:
《用Python写网络爬虫》[本书代码]
================================================================================