3种抓取其中数据的方法,你都知道吗?


3种抓取其中数据的方法,你都知道吗?

文章插图
3种方法来抓取其中的数据 。首先是正则表达式,然后是流行的模块,最后是强大的 lxml 模块 。
1 正则表达式
如果您是正则表达式的新手,或者需要一些提示,您可以查看它以获得完整的介绍 。即使你在其他编程语言中使用过正则表达式,我仍然建议你逐步复习中文正则表达式的编写 。
由于可以在每章中构建或使用前几章的内容,因此我建议您遵循类似于本书代码库的文件结构 。所有代码都可以从代码库的代码目录运行,以便导入工作正常 。如果您希望创建不同的结构,请注意所有来自其他章节的导入都需要更改(例如,来自下面代码中的 chp1.r) 。
当我们使用正则表达式获取国家(或地区)地区数据时,首先需要尝试匹配``元素中的内容,如下图所示 。
>>> 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)['
3种抓取其中数据的方法,你都知道吗?

文章插图

是一个非常流行的库,它解析网页并提供方便的界面来定位内容 。如果您尚未安装该模块,您可以使用以下命令安装其最新版本 。
pip install beautifulsoup4
使用 Soup 的第一步是将下载的 HTML 内容解析成一个汤文档 。由于许多网页不是格式良好的 HTML,因此 Soup 需要更正其标签的打开和关闭状态 。例如,在下面这个简单网页的清单中,存在属性值和未闭合标签周围缺少引号的问题 。
  • Area
  • Population

如果列表项被解析为 Area 列表项的子项,而不是两个并排的列表项,我们将在获取时得到错误的结果 。让我们看看 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 。没有得到正确解析的 HTML 。从前面的代码片段可以看出,由于它使用了嵌套的 li 元素,会导致定位困难 。幸运的是,我们还有其他解析器可供选择 。我们可以安装 LXML(详见 2.2.3 部分),或者使用 . 要安装,只需使用 pip 。
pip install html5lib
现在,我们可以重复此代码,只需对解析器进行以下更改 。
>>> soup = BeautifulSoup(broken_html, 'html5lib')>>> fixed_html = soup.prettify()>>> pprint(fixed_html)
  • Area
  • Population

此时,使用的已经正确解析了缺少的属性引号和结束标记,并且还添加了和标记,使其成为一个完整的 HTML 文档 。使用 lxml 时也可以看到类似的结果 。
现在,我们可以使用 find() 和 () 方法来定位我们需要的元素 。
>>> 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

  • 有关可用方法和参数的完整列表,请访问 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