3种抓取其中数据的方法。首先是正则表达式,然后是流行的BeautifulSoup模块,最后是强大的lxml模块。

1 正则表达式

如果你对正则表达式还不熟悉,或是需要一些提示,那么你可以查阅https://docs.python.org/2/howto/regex.html获得完整介绍。即使你使用过其他编程语言的正则表达式,我依然推荐你一步一步温习一下Python中正则表达式的写法。

由于每章中都可能构建或使用前面章节的内容,因此我建议你按照类似本书代码库的文件结构进行配置。所有代码都可以从代码库的code目录中运行,以便导入工作正常。如果你希望创建一个不同的结构,请注意需要变更所有来自其他章的导入操作(比如下述代码中的from chp1.advanced_link_crawler)。

当我们使用正则表达式抓取国家(或地区)面积数据时,首先需要尝试匹配``元素中的内容,如下所示。

>>> import re>>> from chp1.advanced_link_crawler import download>>> url = 'http://example.python-scraping.com/view/UnitedKingdom-239'>>> html = download(url)>>> re.findall(r'(.*?)', html)['', '244,820 square kilometres', '62,348,447', 'GB', 'United Kingdom', 'London', 'EU', '.uk', 'GBP', 'Pound', '44', '@# #@@|@## #@@|@@# #@@|@@## #@@|@#@ #@@|@@#@ #@@|GIR0AA', '^(([A-Z]d{2}[A-Z]{2})|([A-Z]d{3}[A-Z]{2})|([A-Z]{2}d{2} [A-Z]{2})|([A-Z]{2}d{3}[A-Z]{2})|([A-Z]d[A-Z]d[A-Z]{2}) |([A-Z]{2}d[A-Z]d[A-Z]{2})|(GIR0AA))$', 'en-GB,cy-GB,gd', '
IE

']

从上述结果中可以看出,多个国家(或地区)属性都使用了``标签。如果我们只想抓取国家(或地区)面积,可以只选择第二个匹配的元素,如下所示。

>>> re.findall('(.*?)', html)[1]'244,820 square kilometres'

虽然现在可以使用这个方案,但是如果网页发生变化,该方案很可能就会失效。比如表格发生了变化,去除了第二个匹配元素中的面积数据。如果我们只在当下抓取数据,就可以忽略这种未来可能发生的变化。但是,如果我们希望在未来某一时刻能够再次抓取该数据,就需要给出更加健壮的解决方案,从而尽可能避免这种布局变化所带来的影响。想要该正则表达式更加明确,我们可以将其父元素``也加入进来,由于该元素具有ID属性,所以应该是唯一的。

>>> re.findall('Area: (.*?)', html)['244,820 square kilometres']

这个迭代版本看起来更好一些,但是网页更新还有很多其他方式,同样可以让该正则表达式无法满足。比如,将双引号变为单引号,`标签之间添加多余的空格,或是变更area_label`等。下面是尝试支持这些可能性的改进版本。

>>> re.findall('''.*?(.*?)''', html)['244,820 square kilometres']

虽然该正则表达式更容易适应未来变化,但又存在难以构造、可读性差的问题。此外,还有很多其他微小的布局变化也会使该正则表达式无法满足,比如在`标签里添加title属性,或者tr、td`元素修改了它们的CSS类或ID。

从本例中可以看出,正则表达式为我们提供了抓取数据的快捷方式,但是该方法过于脆弱,容易在网页更新后出现问题。幸好,还有更好的数据抽取解决方案,比如我们将在本章介绍的其他抓取库。

2 Beautiful Soup

Beautiful Soup

是一个非常流行的Python库,它可以解析网页,并提供了定位内容的便捷接口。如果你还没有安装该模块,可以使用下面的命令安装其最新版本。

pip install beautifulsoup4

使用Beautiful Soup的第一步是将已下载的HTML内容解析为soup文档。由于许多网页都不具备良好的HTML格式,因此Beautiful Soup需要对其标签开合状态进行修正。例如,在下面这个简单网页的列表中,存在属性值两侧引号缺失和标签未闭合的问题。

  • Area
  • Population

如果Population列表项被解析为Area列表项的子元素,而不是并列的两个列表项的话,我们在抓取时就会得到错误的结果。下面让我们看一下Beautiful Soup是如何处理的。

>>> from bs4 import BeautifulSoup>>> from pprint import pprint>>> broken_html = '
  • Area
  • Population

'>>> # parse the HTML>>> soup = BeautifulSoup(broken_html, 'html.parser')>>> fixed_html = soup.prettify()>>> pprint(fixed_html)

  • Area
  • Population

我们可以看到,使用默认的html.parser并没有得到正确解析的HTML。从前面的代码片段可以看出,由于它使用了嵌套的li元素,因此可能会导致定位困难。幸运的是,我们还有其他解析器可以选择。我们可以安装LXML(2.2.3节中将会详细介绍),或使用html5lib。要想安装html5lib,只需使用pip。

pip install html5lib

现在,我们可以重复这段代码,只对解析器做如下变更。

>>> soup = BeautifulSoup(broken_html, 'html5lib')>>> fixed_html = soup.prettify()>>> pprint(fixed_html) 
  • Area
  • Population

此时,使用了html5lib的BeautifulSoup已经能够正确解析缺失的属性引号以及闭合标签,并且还添加了和标签,使其成为完整的HTML文档。当你使用lxml时,也可以看到类似的结果。

现在,我们可以使用find()和find_all()方法来定位我们需要的元素了。

>>> ul = soup.find('ul', attrs={'class':'country_or_district'})>>> ul.find('li') # returns just the first match

Area>>> ul.find_all('li') # returns all matches[Area, Population

想要了解可用方法和参数的完整列表,请访问Beautiful Soup的官方文档。

下面是使用该方法抽取示例网站中国家(或地区)面积数据的完整代码。

>>> from bs4 import BeautifulSoup>>> url = 'http://example.python-scraping.com/places/view/United-Kingdom-239'>>> html = download(url)>>> soup = BeautifulSoup(html)>>> # locate the area row>>> tr = soup.find(attrs={'id':'places_area__row'})>>> td = tr.find(attrs={'class':'w2p_fw'}) # locate the data element>>> area = td.text # extract the text from the data element>>> print(area)244,820 square kilometres

这段代码虽然比正则表达式的代码更加复杂,但又更容易构造和理解。而且,像多余的空格和标签属性这种布局上的小变化,我们也无须再担心了。我们还知道即使页面中包含了不完整的HTML,Beautiful Soup也能帮助我们整理该页面,从而让我们可以从非常不完整的网站代码中抽取数据。

3 Lxml

Lxml

是基于libxml2这一XML解析库构建的Python库,它使用C语言编写,解析速度比Beautiful Soup更快,不过安装过程也更为复杂,尤其是在Windows中。最新的安装说明可以参考http://lxml.de/installation.html。如果你在自行安装该库时遇到困难,也可以使用Anaconda来实现。

你可能对Anaconda不太熟悉,它是由Continuum Analytics公司员工创建的主要专注于开源数据科学包的包和环境管理器。你可以按照其安装说明下载及安装Anaconda。需要注意的是,使用Anaconda的快速安装会将你的PYTHON_PATH设置为Conda的Python安装位置。

和Beautiful Soup一样,使用lxml模块的第一步也是将有可能不合法的HTML解析为统一格式。下面是使用该模块解析同一个不完整HTML的例子。

>>> from lxml.html import fromstring, tostring>>> broken_html = '
  • Area
  • Population

'>>> tree = fromstring(broken_html) # parse the HTML>>> fixed_html = tostring(tree, pretty_print=True)>>> print(fixed_html)

  • Area
  • Population

同样地,lxml也可以正确解析属性两侧缺失的引号,并闭合标签,不过该模块没有额外添加和标签。这些都不是标准XML的要求,因此对于lxml来说,插入它们并不是必要的。

解析完输入内容之后,进入选择元素的步骤,此时lxml有几种不同的方法,比如XPath选择器和类似Beautiful Soup的find()方法。不过,在本例中,我们将会使用CSS选择器,因为它更加简洁,并且能够在第5章解析动态内容时得以复用。一些读者可能由于他们在jQuery选择器方面的经验或是前端Web应用开发中的使用对它们已经有所熟悉。在本章的后续部分,我们将对比这些选择器与XPath的性能。要想使用CSS选择器,你可能需要先安装cssselect库,如下所示。

pip install 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 square kilometres

通过对代码树使用cssselect方法,我们可以利用CSS语法来选择表格中ID为places_area__row的行元素,然后是类为w2p_fw的子表格数据标签。由于cssselect返回的是一个列表,我们需要获取其中的第一个结果,并调用text_content方法,以迭代所有子元素并返回每个元素的相关文本。在本例中,尽管我们只有一个元素,但是该功能对于更加复杂的抽取示例来说非常有用。

本文摘自:《用Python写网络爬虫(第2版)》

作者:[德]凯瑟琳 雅姆尔(Katharine Jarmul)、[澳]理查德 劳森(Richard Lawson)

译者:李斌

针对Python 3.6版本编写。


提供示例完整源码和实例网站搭建源码,确保用户能在本地成功复现爬取网站环境,并保障网站的稳定性与可靠性以及代码运行结果的可再现性。


Internet上包含了许多有用的数据,其中大部分是可以免费公开访问的。但是,这些数据不容易使用,它们内嵌在网站的架构和样式中,在提取时也需要多加小心。网络爬取技术作为一种收集和理解网络上海量信息的方式,正变得越来越有用。


本书是使用Python 3.6的新特性来爬取网络数据的入门指南。本书讲解了从静态网站提取数据的方法,以及如何使用数据库和文件缓存技术来节省时间并管理服务器负载,然后介绍了如何使用浏览器、爬虫和并发爬虫开发一个更为复杂的爬虫。


借助于PyQt和Selenium,你可以决定何时以及如何从依赖JavaScript的网站上爬取数据,以及更好地理解在受CAPTCHA保护的复杂网站上提交表单的方法。本书还讲解了使用Python包(比如mechanize)进行自动化处理的方法、使用Scrapy库创建基于类的爬虫的方法,以及如何在真实的网站上实施所学的爬虫技巧。


本书最后还涵盖了使用爬虫对网站进行测试、远程爬取技术、图像处理以及其他相关的主题。

golang:正则表达式匹配网页url_网络爬虫:3种网页抓取方法相关推荐

  1. 网络爬虫——票房网数据抓取及存储

    网络爬虫--票房网数据抓取及存储 实验内容 目标网站:电影票房网 目标网址:http://58921.com/daily/wangpiao 任务要求 目标数据:(1)名次(2)电影名称 (3)日期(4 ...

  2. Python,网络爬虫selenium与pyautogui抓取新浪微博用户数据

    Python,网络爬虫selenium与pyautogui抓取新浪微博用户数据 不需要登陆新浪微博账户,直接运行就可以通过python爬虫爬取新浪微博用户数据.本例selenium与pyautogui ...

  3. 网络爬虫中进行数据抓取

    以下内容是<用python写网络爬虫>的读书笔记 一.安装firebug lite firebug lite是一个用于在网站中查看调试html,css和javascript的有效工具.它现 ...

  4. Node.js学习之网络爬虫(使用cheerio抓取网页数据)

    准备工作 1.安装node.js开发环境:http://www.runoob.com/nodejs/nodejs-install-setup.html 2.了解cheerio库 英文:https:// ...

  5. python抓取网页数据并截图_网络爬虫-使用Python抓取网页数据

    搬自大神boyXiong的干货! 闲来无事,看看了Python,发现这东西挺爽的,废话少说,就是干 准备搭建环境 因为是MAC电脑,所以自动安装了Python 2.7的版本 添加一个 库 Beauti ...

  6. 网络爬虫-模拟手机浏览器抓取数据

    有些网站的数据在PC端很复杂,参数加密很严重,但是移动APP端的就没那么多加密,所以在遇到有些瓶颈的情况下,可以考虑从网页端转到移动端去抓包,爬取数据.这里有两种方法: 一. 使用模拟器下载APP 如 ...

  7. 浅谈屏蔽搜索引擎爬虫(蜘蛛)抓取/索引/收录网页的几种思路

    在大部分情况下,网站开发完成后,在运营期间,都希望搜索引擎收录网站的内容越多越好,但是有的时候为了安全期间不希望搜索引擎收录网页内容,比如在外网部署的监控系统等:  以下列举了屏蔽主流搜索引擎爬虫(蜘 ...

  8. [Python爬虫] 三、数据抓取之Requests HTTP 库

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 一.urllib 模块 所谓网页抓取,就是把URL ...

  9. Python爬虫实战六之抓取爱问知识人问题并保存至数据库

    大家好,本次为大家带来的是抓取爱问知识人的问题并将问题和答案保存到数据库的方法,涉及的内容包括: Urllib的用法及异常处理 Beautiful Soup的简单应用 MySQLdb的基础用法 正则表 ...

最新文章

  1. Node.js 和Socket.IO 实现chat
  2. 【LeetCode】462. 最少移动次数使数组元素相等 II
  3. ROW_NUMBER、RANK、DENSE_RANK的用法
  4. ORACLE TEXT LEXER PREFERENCE(四)
  5. [LeetCode] Find All Numbers Disappeared in an Array 找出数组中所有消失的数字
  6. Kubernetes-命名空间namespace(ns)(十四)
  7. linux查看允许创建多少个进程,Linux下查看某个进程创建了多少线程
  8. 三年期定期存款利率多少?
  9. 2020 开春程序员面试必备!拿走不谢!
  10. ajax编辑教程,今天手动编写了一个简易的 ajax 发起器(JavaScript)
  11. 2017锤子科技发布会
  12. uni-app入门到项目实战
  13. 立体栅格地图_高精地图之3D栅格地图的应用
  14. 形容计算机网络教室的成语,形容教育的成语
  15. Windows安装 choco包管理工具
  16. 马来西亚数字自由贸易区的发展实践
  17. 国民感冒众生相,“微大夫”电磁脉冲预防+舒缓
  18. 2018下半年计算机学科竞赛,2018年度下半年五大学科竞赛,其他赛事时间预告高一高二请收好,不要错过报名.doc...
  19. 随笔-杂记-将对您的电脑造成伤害。 您应该将它移到废纸篓
  20. 据说,2021年Apple将推出1416英寸MacBook Pro

热门文章

  1. 计算器小程序java课程设计,java课程设计----计算器小程序报告.doc
  2. c语言中建一个文件的语法,C语言语法介绍_文件.ppt
  3. java输出动物,求大神帮助输出为什么只有动物名,几条腿,怎么叫,没有汤姆猫叫等...
  4. excel日期格式改不了_画进度计划横道图,Excel就够了
  5. terminal mysql 停止_转载MySQL之终端(Terminal)管理MySQL
  6. linux下的malloc申请的是虚拟还是物理的,关于malloc申请内存
  7. php的类有全局变量吗_解析在PHP中使用全局变量的几种方法
  8. java. 三个人比赛怎么写_两个乒乓球队进行比赛,找出三队赛手的名单
  9. python反编译加密文件_python打包的二进制文件反编译
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的二手房交易系统