本章我们将学习网络爬虫,其中包括学习Python中的​​BeautifulSoup​​库,它用于从网站中提取数据。

本章包含以下主题。

  • 什么是网络爬虫。
  • 数据提取。
  • 从维基百科网站提取信息。

1 什么是网络爬虫

网络爬虫是指从网站提取数据的技术,该技术可以将非结构化数据转换为结构化数据。

网络爬虫的用途是从网站提取数据,提取的数据可以存储到本地文件并保存在系统中,也可以将其以表格的形式存储到数据库中。网络爬虫使用HTTP或Web浏览器直接访问万维网(WWW)。网络爬虫或机器人抓取网页的过程是一个自动化流程。

抓取网页的过程分为获取网页、提取数据。Web抓取程序可以获取网页,它是网络爬虫的必需组件。在获取网页后,就需要提取网页数据了。我们可以搜索、解析,并将提取的数据保存到表格中,然后重新整理格式。

2 数据提取

本节我们学习数据提取。我们可以使用Python的​​BeautifulSoup​​​库进行数据提取。这里还需要用到Python库的​​Requests​​模块。

运行以下命令以安装​​Requests​​​和​​BeautifulSoup​​库。

$ pip3 install requests
$ pip3 install beautifulsoup4

2.1 Requests库

使用​​Requests​​​库可以易懂的格式在Python脚本中使用HTTP,这里使用Python中的​​Requests​​​库获取网页。​​Requests​​​库包含不同类型的请求,这里使用​​GET​​​请求。​​GET​​​请求用于从Web服务器获取信息,使用​​GET​​请求可以获取指定网页的HTML内容。每个请求都对应一个状态码,状态码从服务器返回,这些状态码为我们提供了对应请求执行结果的相关信息。以下是部分状态码。

  • ​200​​:表示一切正常并返回结果(如果有)。
  • ​301​​:表示如果服务器已切换域名或必须更改端点名称,则服务器将重定向到其他端点。
  • ​400​​:表示用户发出了错误请求。
  • ​401​​:表示用户未通过身份验证。
  • ​403​​:表示用户正在尝试访问禁用的资源。
  • ​404​​:表示用户尝试访问的资源在服务器上不可用。

2.2 BeautifulSoup库

​BeautifulSoup​​也是一个Python库,它包含简单的搜索、导航和修改方法。它只是一个工具包,用于从网页中提取所需的数据。

要在脚本中使用​​Requests​​​和​​BeautifulSoup​​​模块,必须使用​​import​​​语句导入这两个模块。现在我们来看一个解析网页的示例程序,这里将解析一个来自百度网站的新闻网页。创建一个脚本,命名为​​parse_web_page.py​​,并在其中写入以下代码。

import requests
from bs4 import BeautifulSoup

page_result = requests.get('https://www.news.baidu.com')
parse_obj = BeautifulSoup(page_result.content, 'html.parser')

print(parse_obj)

运行脚本程序,如下所示。

student@ubuntu:~/work$ python3 parse_web_page.py
Output:
<!DOCTYPE html>

<html xmlns:fb="http://www.facebook.com/2008/fbml"
xmlns:og="http://ogp.me/ns#">
<head>
<meta charset="utf-8"/>
<meta content="IE=edge" http-equiv="X-UA-Compatible"/>
<meta content="app-id=342792525, app-argument=imdb:///?src=mdot"
name="apple-itunes-app"/>
<script type="text/javascript">var IMDbTimer={starttime: new
Date().getTime(),pt:'java'};</script>
<script>
if (typeof uet == 'function') {
uet("bb", "LoadTitle", {wb: 1});
}
</script>
<script>(function(t){ (t.events = t.events || {})["csm_head_pre_title"] =
new Date().getTime(); })(IMDbTimer);</script>
<title>Top News - IMDb</title>
<script>(function(t){ (t.events = t.events || {})["csm_head_post_title"] =
new Date().getTime(); })(IMDbTimer);</script>
<script>
if (typeof uet == 'function') {
uet("be", "LoadTitle", {wb: 1});
}
</script>
<script>
if (typeof uex == 'function') {
uex("ld", "LoadTitle", {wb: 1});
}
</script>
<link href="https://www.imdb.com/news/top" rel="canonical"/>
<meta content="http://www.imdb.com/news/top" property="og:url">
<script>
if (typeof uet == 'function') {
uet("bb", "LoadIcons", {wb: 1});
}

上面的示例程序抓取了一个网页,并使用​​BeautifulSoup​​​对其进行了解析。首先导入了​​requests​​​和​​BeautifulSoup​​​模块,然后使用GET请求访问URL,并将结果分配给​​page_result​​​变量,接着创建了一个​​BeautifulSoup​​​对象​​parse_obj​​​,此对象将​​requests​​​的返回结果​​page_result.content​​​作为参数,然后使用​​html.parser​​解析该页面。

现在我们将从类和标签中提取数据。转到Web浏览器,右击要提取的内容并向下查找,找到“检查”选项,单击它将获得类名。在程序中指定这个类名,并运行脚本。创建一个脚本,命名为​​extract_from_class.py​​,并在其中写入以下代码。

import requests
from bs4 import BeautifulSoup

page_result = requests.get('https://www.news.baidu.com')
parse_obj = BeautifulSoup(page_result.content, 'html.parser')

top_news = parse_obj.find(class_='news-article__content')
print(top_news)

运行脚本程序,如下所示。

student@ubuntu:~/work$ python3 extract_from_class.py
Output :
<div class="news-article__content">
<a href="/name/nm4793987/">Issa Rae</a> and <a
href="/name/nm0000368/">Laura Dern</a> are teaming up to star in a limited
series called "The Dolls" currently in development at <a
href="/company/co0700043/">HBO</a>.<br/><br/>Inspired by true events, the
series recounts the aftermath of Christmas Eve riots in two small Arkansas
towns in 1983, riots which erupted over Cabbage Patch Dolls. The series
explores class, race, privilege and what it takes to be a "good
mother."<br/><br/>Rae will serve as a writer and executive producer on the
series in addition to starring, with Dern also executive producing. <a
href="/name/nm3308450/">Laura Kittrell</a> and <a
href="/name/nm4276354/">Amy Aniobi</a> will also serve as writers and coexecutive
producers. <a href="/name/nm0501536/">Jayme Lemons</a> of Dern’s
<a href="/company/co0641481/">Jaywalker Pictures</a> and <a
href="/name/nm3973260/">Deniese Davis</a> of <a
href="/company/co0363033/">Issa Rae Productions</a> will also executive
produce.<br/><br/>Both Rae and Dern currently star in HBO shows, with Dern
appearing in the acclaimed drama "<a href="/title/tt3920596/">Big Little
Lies</a>" and Rae starring in and having created the hit comedy "<a
href="/title/tt5024912/">Insecure</a>." Dern also recently starred in the
film "<a href="/title/tt4015500/">The Tale</a>,
</div>

上面的示例程序首先导入了​​requests​​​和​​BeautifulSoup​​​模块,然后创建了一个​​requests​​​对象并为其分配了一个URL,接着创建了一个​​BeautifulSoup​​​对象​​parse_obj​​​。此对象将​​requests​​​的返回结果​​page_result.content​​​作为参数,然后使用​​html.parser​​​解析页面。最后,使用​​BeautifulSoup​​​的​​find()​​​方法从​​news-article__content​​类中获取内容。

现在我们来看一个从特定标签中提取数据的示例程序,此示例程序将从​​<a>​​​标签中提取数据。创建一个脚本,命名为​​extract_from_tag.py​​,并在其中写入以下代码。

import requests
from bs4 import BeautifulSoup

page_result = requests.get('https://www.news.baidu.com/news')
parse_obj = BeautifulSoup(page_result.content, 'html.parser')

top_news = parse_obj.find(class_='news-article__content')
top_news_a_content = top_news.find_all('a')
print(top_news_a_content)

运行脚本程序,如下所示。

student@ubuntu:~/work$ python3 extract_from_tag.py
Output:
[<a href="/name/nm4793987/">Issa Rae</a>, <a href="/name/nm0000368/">Laura
Dern</a>, <a href="/company/co0700043/">HBO</a>, <a
href="/name/nm3308450/">Laura Kittrell</a>, <a href="/name/nm4276354/">Amy
Aniobi</a>, <a href="/name/nm0501536/">Jayme Lemons</a>, <a
href="/company/co0641481/">Jaywalker Pictures</a>, <a
href="/name/nm3973260/">Deniese Davis</a>, <a
href="/company/co0363033/">Issa Rae Productions</a>, <a
href="/title/tt3920596/">Big Little Lies</a>, <a
href="/title/tt5024912/">Insecure</a>, <a href="/title/tt4015500/">The
Tale</a>]

上面的示例程序从​​<a>​​​标签中提取数据。这里使用​​find_all()​​​方法从​​news-article__content​​​类中提取所有​​<a>​​标签数据。

3 从维基百科网站抓取信息

本节我们将学习一个从维基百科网站获取舞蹈种类列表的示例程序,这里将列出所有古典印度舞蹈。创建一个脚本,命名为​​extract_from_wikipedia.py​​,并在其中写入以下代码。

import requests
from bs4 import BeautifulSoup

page_result = requests.get('https://en.wikipedia.org/wiki/Portal:History')
parse_obj = BeautifulSoup(page_result.content, 'html.parser')

h_obj = parse_obj.find(class_='hlist noprint')
h_obj_a_content = h_obj.find_all('a')

print(h_obj)
print(h_obj_a_content)

运行脚本程序,如下所示。

student@ubuntu:~/work$ python3 extract_from_wikipedia.py

输出如下。

<div class="hlist noprint" id="portals-browsebar" style="text-align:
center;">
<dl><dt><a href="/wiki/Portal:Contents/Portals"
title="Portal:Contents/Portals">Portal topics</a></dt>
<dd><a href="/wiki/Portal:Contents/Portals#Human_activities"
title="Portal:Contents/Portals">Activities</a></dd>
<dd><a href="/wiki/Portal:Contents/Portals#Culture_and_the_arts"
title="Portal:Contents/Portals">Culture</a></dd>
<dd><a href="/wiki/Portal:Contents/Portals#Geography_and_places"
title="Portal:Contents/Portals">Geography</a></dd>
<dd><a href="/wiki/Portal:Contents/Portals#Health_and_fitness"
title="Portal:Contents/Portals">Health</a></dd>
<dd><a href="/wiki/Portal:Contents/Portals#History_and_events"
title="Portal:Contents/Portals">History</a></dd>
<dd><a href="/wiki/Portal:Contents/Portals#Mathematics_and_logic"
title="Portal:Contents/Portals">Mathematics</a></dd>
<dd><a href="/wiki/Portal:Contents/Portals#Natural_and_physical_sciences"
title="Portal:Contents/Portals">Nature</a></dd>
<dd><a href="/wiki/Portal:Contents/Portals#People_and_self"
title="Portal:Contents/Portals">People</a></dd>
In the preceding example, we extracted the content from Wikipedia. In this
example also, we extracted the content from class as well as tag.
....

4 总结

在本章中,我们学习了网络爬虫的有关内容,其中学习了两个用于从网页中提取数据的库,还学习了从维基百科网站提取信息。

在第17章中,我们将学习统计信息的收集和报告。其中将学习NumPy模块,数据可视化以及使用plots、graphs和charts显示数据。

5 问题

1.什么是网络爬虫?

2.什么是网络抓取工具?

3.我们可以从需要登录的网页抓取数据吗?

4.我们可以爬取Twitter网站数据吗?

5.我们是否可以爬取Java脚本页面数据?如果可以,怎么做?

[印度] 甘尼什·桑吉夫·奈克(Ganesh,Sanjiv,Naik) 著,张成悟 译

网络爬虫——从网站中提取有用的数据_python

本书首先介绍Python的安装,并讲解编程基础知识。然后,本书将侧重于解析整个开发过程,从配置到准备再到构建 不同的工具,包括IT管理员的日常活动(文本处理、正则表达式、文件存档和加密)、网络管理(套接字编程、电子邮 件处理、使用Telnet/SSH远程控制设备以及SNMP/DHCP等协议)、创建图形用户界面、网站处理(Apache日志 文件处理、SOAP和REST API通信、Web抓取),以及数据库管理(MySQL和相似数据库数据管理、数据分析和报告)。学完本书,读者将能够使用Python功能构建强大的工具以解决具有挑战性的实际任务。

读者将学到以下内容:

■ 了解如何安装Python和调试Python脚本;

■ 了解和编写用于自动化测试和日常管理活动的脚本;

■ 了解如何编写用于文本处理、加密、解密和归档的脚本;

■ 处理PDF、Excel、CSV和文本文件,并生成报告;

■ 编写用于远程网络管理(包括处理电子邮件)的脚本;

■ 使用图形用户界面构建交互式工具;

■ 处理Apache日志文件,以及SOAP和REST API的通信;

■ 自动化数据库管理并执行统计分析。