正则表达式国家(或地区)面积数据抓取其中数据的方法
优采云 发布时间: 2021-07-08 01:39正则表达式国家(或地区)面积数据抓取其中数据的方法
3 种捕获数据的方法。首先是正则表达式,然后是流行的 BeautifulSoup 模块,最后是强大的 lxml 模块。
1正则表达式
如果你不熟悉正则表达式或者需要一些提示,那么你可以查看完整的介绍。即使你用过其他编程语言的正则表达式,我还是建议你一步一步复习Python中正则表达式的编写。
因为每一章都可能构建或使用前几章的内容,所以建议你遵循类似于本书代码库的文件结构。所有代码都可以从代码库的代码目录运行,这样导入才能正常进行。如果要创建不同的结构,请注意其他章节的所有导入操作都需要更改(例如以下代码中的chp1.advanced_link_crawler)。
当我们使用正则表达式抓取一个国家(或地区)的面积数据时,首先需要尝试匹配``元素中的内容,如下图。
>>> import re>>> from chp1.advanced_link_crawler import download>>> url ='#39;>>> html = download(url)>>> re.findall(r'(.*? )', html)['
','244,820 平方公里','62,348,447','GB','英国','伦敦','EU','.uk','GBP','英镑','44',' @##@@|@###@@|@@##@@|@@###@@|@#@ #@@|@@#@ #@@|GIR0AA','^(( [AZ]d{2}[AZ]{2})|([AZ]d{3}[AZ]{2})|([AZ]{2}d{2} [AZ]{2})| ([AZ]{2}d{3}[AZ]{2})|([AZ]d[AZ]d[AZ]{2})|([AZ]{2}d[AZ]d[AZ] ]{2})|(GIR0AA))$','en-GB,cy-GB,gd','
浏览器
']
从上面的结果可以看出,多个国家(或地区)属性使用了``标签。如果我们只想捕获国家(或地区)的面积,我们可以只选择第二个匹配元素,如下图。
>>> re.findall('(.*?)', html)[1]'244,820 平方公里'
虽然现在可以使用这个计划,但是如果页面发生变化,该计划很可能会失败。例如,表发生了变化,删除了第二个匹配元素中的区域数据。如果我们现在只抓取数据,我们可以忽略这种可能的未来变化。但是,如果我们希望能够在未来的某个时刻再次捕获数据,我们需要提供更健壮的解决方案,以尽可能避免这种布局更改的影响。为了使正则表达式更加明确,我们还可以添加其父元素。因为这个元素有一个 ID 属性,所以它应该是唯一的。
>>> re.findall('(.*?)', html)['244,820 平方公里']
这个迭代版本看起来更好,但是还有很多其他的更新网页的方式,也会让正则表达式不尽人意。例如,将双引号改为单引号,在`labels 之间添加额外的空格,或者更改area_label` 等。下面是一个尝试支持这些可能性的改进版本。
>>> re.findall('''.*?(.*?)''', html)['244,820平方公里']
这个正则表达式虽然更容易适应未来的变化,但存在构建困难、可读性差的问题。此外,还有许多其他细微的布局更改会使正则表达式不令人满意,例如在`tag 中添加title 属性,或者为tr 和td` 元素修改其CSS 类或ID。
从这个例子中可以看出,正则表达式为我们提供了一种快速抓取数据的方式,但是这种方式过于脆弱,而且很容易在网页更新后出现问题。幸运的是,还有更好的数据提取解决方案,例如我们将在本章中介绍的其他爬虫库。
2美汤
美汤
是一个非常流行的 Python 库,可以解析网页并提供方便的界面来定位内容。如果您还没有安装该模块,可以使用以下命令安装最新版本。
pip install beautifulsoup4
使用 Beautiful Soup 的第一步是将下载的 HTML 内容解析成一个 Soup 文档。由于很多网页没有好的HTML格式,Beautiful Soup需要修改其标签打开和关闭状态。例如,在下面的简单网页列表中,存在属性值周围缺少引号和未关闭标签的问题。
如果将 Population 列表项解析为 Area 列表项的子元素,而不是两个并排的列表项,我们在爬行时会得到错误的结果。下面我们来看看Beautiful Soup是如何处理的。
>>> from bs4 import BeautifulSoup>>> from pprint import pprint>>>broken_html =''>>> # 解析HTML>>>soup = BeautifulSoup(broken_html,'html.parser')>>> fixed_html =soup.prettify()>>> pprint(fixed_html)
我们可以看到,使用默认的 html.parser 无法正确解析 HTML。从前面的代码片段可以看出,由于使用了嵌套的li元素,可能会造成定位困难。幸运的是,我们还有其他解析器可供选择。我们可以安装 LXML(详见2.2.3 部分),或者使用 html5lib。要安装 html5lib,只需使用 pip。
pip 安装 html5lib
现在,我们可以重复这段代码,只对解析器进行以下更改。
>>>soup = BeautifulSoup(broken_html,'html5lib')>>> fixed_html = soup.prettify()>>> pprint(fixed_html)
此时使用html5lib的BeautifulSoup已经能够正确解析缺失的属性引号和结束标签,并添加&标签使其成为完整的HTML文档。当你使用 lxml 时,你可以看到类似的结果。
现在,我们可以使用 find() 和 find_all() 方法来定位我们需要的元素。
>>> ul = soup.find('ul', attrs=('class':'country_or_district'))>>> ul.find('li') # 只返回第一个匹配区域>>> ul. find_all('li') # 返回所有匹配项[Area, Population
有关可用方法和参数的完整列表,请访问 Beautiful Soup 的官方文档。
以下是使用该方法提取样本网站中国家(或地区)面积数据的完整代码。
>>> from bs4 import BeautifulSoup>>> url ='#39;>>> html = download(url)>>> soup = BeautifulSoup(html)>>> # 定位区域行>>> tr = soup.find(attrs={'id':'places_area__row'})>>>td = tr.find(attrs={'class':'w2p_fw'}) # 定位数据元素>>> area = td.text # 从数据元素中提取文本>>> print(area)244,820 平方公里
虽然这段代码比正则表达式代码复杂,但更容易构建和理解。此外,我们不需要担心布局的微小变化,例如额外的空间和标签属性。我们也知道,即使页面收录不完整的 HTML,Beautiful Soup 也可以帮助我们组织页面,以便我们从非常不完整的网站 代码中提取数据。
3Lxml
Lxml
它是一个基于 libxml2 构建的 Python 库,一个 XML 解析库。它是用C语言编写的,解析速度比Beautiful Soup更快,但安装过程比较复杂,尤其是在Windows下。您可以参考最新的安装说明。如果自己安装库有困难,也可以使用Anaconda来实现。
您可能不熟悉 Anaconda。它是一个由员工创建的包和环境管理器,专注于开源数据科学包。您可以根据其安装说明下载并安装 Anaconda。需要注意的是,使用Anaconda的快速安装会将你的PYTHON_PATH设置为Conda的Python安装位置。
和 Beautiful Soup 一样,使用 lxml 模块的第一步是将潜在的非法 HTML 解析为统一格式。下面是使用该模块解析同样不完整的 HTML 的示例。
>>> from lxml.html import fromstring, tostring>>>broken_html =''>>> tree = fromstring(broken_html) # 解析HTML>>>fixed_html = tostring(tree,pretty_print=True)>>>打印(fixed_html)
同理,lxml 也可以正确解析属性两边缺失的引号并关闭标签,但是模块没有添加额外的 and 标签。这些不是标准 XML 的要求,所以对于 lxml 来说,插入它们是没有必要的。
解析输入内容后,进入选择元素的步骤。这时候lxml有几种不同的方法,比如XPath选择器和类似于Beautiful Soup的find()方法。但是,在这个例子中,我们将使用 CSS 选择器,因为它更简洁,可以在第 5 章解析动态内容时重复使用。 一些读者可能已经熟悉了它们,因为他们有过 jQuery 选择器的经验或它们在前面的使用——结束 Web 应用程序开发。在本章的其余部分,我们将比较这些选择器与 XPath 的性能。要使用 CSS 选择器,您可能需要先安装 cssselect 库,如下所示。
pip 安装 cssselect
现在,我们可以使用 lxml 的 CSS 选择器来提取示例页面中的区域数据。
>>> tree = fromstring(html)>>> td = tree.cssselect('tr#places_area__row> td.w2p_fw')[0]>>> area = td.text_content()>>> print(area )244,820 平方公里
通过在代码树上使用cssselect方法,我们可以使用CSS语法选择表中ID为places_area__row的行元素,然后选择类w2p_fw的子表数据标签。由于cssselect返回的是一个列表,我们需要获取第一个结果并调用text_content方法迭代所有子元素并返回每个元素的相关文本。在这个例子中,虽然我们只有一个元素,但这个特征对于更复杂的提取例子非常有用。
本文摘自:《Writing Web Crawlers in Python (2nd Edition)》
作者:[德国]凯瑟琳·贾穆尔(Katharine Jarmul)、[澳大利亚]理查德·劳森(Richard Lawson)
译者:李斌
为 Python 3.6 版本编写。
提供示例完整源代码和示例网站构建源代码,确保用户在本地成功重现爬取网站环境,并保证网站的稳定性和可靠性以及代码运行结果的可复现性。
互联网收录大量有用的数据,其中大部分是免费且可公开访问的。然而,这些数据并不容易使用。它们嵌入在网站的结构和样式中,提取时需要小心。作为一种采集和了解 Internet 上信息量的方法,网络抓取技术正变得越来越有用。
本书是使用Python3.6的新特性爬取网络数据的入门指南。本书解释了如何从静态网站中提取数据,以及如何使用数据库和文件缓存技术来节省时间和管理服务器负载,然后介绍如何使用浏览器、爬虫和并发爬虫来开发更复杂的爬虫。
借助 PyQt 和 Selenium,您可以决定何时以及如何从依赖 JavaScript 的 网站 抓取数据,并更好地了解如何在受 CAPTCHA 保护的复杂 网站 上提交表单。书中还讲解了如何使用Python包(如mechanize)进行自动化处理,如何使用Scrapy库创建基于类的爬虫,以及如何实现在真实网站上学到的爬虫技巧。
在本书的最后,它还涵盖了使用爬虫测试网站、远程爬虫技术、图像处理和其他相关主题。