HTML擦除

../_images/34268661876_442428e122_k_d.jpg

Web擦除

网站是使用HTML编写的,这意味着每个网页都是一个结构化文档。有时候从他们那里获得一些数据,并在我们工作的时候保存结构是很好的。网站并不总是以舒适的格式(如csv或json)提供数据。

这就是抓取网页的地方。Web抓取是使用计算机程序筛选网页并以对您最有用的格式收集所需数据,同时保留数据结构的实践。

LXML和请求

lxml 是一个非常广泛的库,用于非常快速地解析XML和HTML文档,甚至在解析过程中处理混乱的标记。我们还将使用 Requests 模块,而不是已经内置的urllib2模块,这是由于速度和可读性的改进。您可以使用以下命令轻松安装这两个软件 pip install lxmlpip install requests

让我们从进口开始:

from lxml import html
import requests

接下来我们将使用 requests.get 要使用数据检索网页,请使用 html 模块,并将结果保存在 tree

page = requests.get('http://econpy.pythonanywhere.com/ex/001.html')
tree = html.fromstring(page.content)

(我们需要使用 page.content 而不是 page.text 因为 html.fromstring 隐式期望 bytes 作为输入。)

tree 现在将整个HTML文件包含在一个很好的树结构中,我们可以通过两种不同的方式:xpath和cssselect。在这个例子中,我们将重点讨论前者。

XPath是一种在结构化文档(如HTML或XML文档)中定位信息的方法。关于xpath的一个很好的介绍已经开始 W3Schools .

还有各种工具可以获取元素的xpath,例如firebug for firefox或chrome inspector。如果使用chrome,可以右键单击元素,选择“inspect element”,突出显示代码,再次右键单击,然后选择“copy xpath”。

经过快速分析,我们发现在我们的页面中,数据包含在两个元素中——一个是标题为“买方名称”的DIV,另一个是标题为“项目价格”的SPAN:

<div title="buyer-name">Carson Busses</div>
<span class="item-price">$29.95</span>

知道了这一点,我们可以创建正确的xpath查询并使用lxml xpath 功能如下:

#This will create a list of buyers:
buyers = tree.xpath('//div[@title="buyer-name"]/text()')
#This will create a list of prices
prices = tree.xpath('//span[@class="item-price"]/text()')

让我们看看我们到底得到了什么:

print('Buyers: ', buyers)
print('Prices: ', prices)
Buyers:  ['Carson Busses', 'Earl E. Byrd', 'Patty Cakes',
'Derri Anne Connecticut', 'Moe Dess', 'Leda Doggslife', 'Dan Druff',
'Al Fresco', 'Ido Hoe', 'Howie Kisses', 'Len Lease', 'Phil Meup',
'Ira Pent', 'Ben D. Rules', 'Ave Sectomy', 'Gary Shattire',
'Bobbi Soks', 'Sheila Takya', 'Rose Tattoo', 'Moe Tell']

Prices:  ['$29.95', '$8.37', '$15.26', '$19.25', '$19.25',
'$13.99', '$31.57', '$8.49', '$14.47', '$15.86', '$11.11',
'$15.98', '$16.27', '$7.50', '$50.85', '$14.26', '$5.68',
'$15.00', '$114.07', '$10.09']

祝贺你!我们已经成功地使用lxml和请求从一个网页中获取了我们想要的所有数据。我们把它作为两个列表存储在内存中。现在我们可以用它做各种各样的酷事情:我们可以使用python分析它,或者我们可以将它保存到一个文件中并与世界共享。

要考虑的一些更酷的想法是修改这个脚本以迭代这个示例数据集的其余页面,或者重写这个应用程序以使用线程来提高速度。