[译] 如何使用 Python 和 BeautifulSoup 爬取网站内容

互联网上的信息量比任何一我的究其一辈子所能掌握的信息量都要大的多。因此咱们要作的不是在互联网上逐个访问信息,而是须要有一种灵活的方式来收集,整理和分析这些信息。html

咱们须要爬取网页数据。前端

网页爬虫能够自动提取出数据并将数据以一种你能够容易理解的形式呈现出来。在本教程中,咱们将重点关注爬虫技术在金融市场中的应用,但实际上网络内容爬取可用于多个领域。python

若是你是一个狂热的投资者,天天获知收盘价可能会是一件很痛苦的事,特别是当你须要的信息分散在多个网页的时候。咱们将经过构建一个网络爬虫来自动从网上检索股票指数,从而简化数据的爬取。mysql

入门

咱们将使用 Python 做为咱们的爬虫语言,还会用到一个简单但很强大的库,BeautifulSoup。android

  • 对于 Mac 用户,OS X 已经预装了 Python。打开终端并输入 python --version。你的 Python 的版本应该是 2.7.x。
  • 对于 Windows 用户,请经过 官方网站 安装 Python。

接下来,咱们须要使用 Python 的包管理工具 pip 来安装 BeautifulSoup 库。ios

在终端中输入:git

easy_install pip  
pip install BeautifulSoup4
复制代码

注意:若是你执行上面的命令发生了错误,请尝试在每一个命令前面添加 sudogithub

基础知识

在咱们真正开始编写代码以前,让咱们先了解下 HTML 的基础知识和一些网页爬虫的规则。web

HTML 标签
若是你已经理解了 HTML 的标签,请跳过这部分。sql

<!DOCTYPE html>  
<html>  
    <head>
    </head>
    <body>
        <h1> First Scraping </h1>
        <p> Hello World </p>
    <body>
</html>
复制代码

下面是一个 HTML 网页的基本语法。网页上的每一个标签都定义了一个内容块:

  1. <!DOCTYPE html>:HTML 文档的开头必须有的类型声明。
  2. HTML 的文档包含在标签 <html> 内。
  3. <head> 标签里面是元数据和 HTML 文档的脚本声明。
  4. <body> 标签里面是 HTML 文档的可视部分。
  5. 标题经过 <h1><h6> 的标签订义。
  6. 段落内容被定义在 <p> 标签里。

其余经常使用的标签还有,用于超连接的 <a> 标签,用于显示表格的 <table> 标签,以及用于显示表格行的 <tr> 标签,用于显示表格列的 <td> 标签。

另外,HTML 标签时常会有 id 或者 class 属性。id 属性定义了标签的惟一标识,而且这个值在当前文档中必须是惟一的。class 属性用来给具备相同类属性的 HTML 标签订义相同的样式。咱们可使用这些 id 和 class 来帮助咱们定位咱们要爬取的数据。

须要更多关于 HTML 标签idclass 的相关内容,请参考 W3Schools 网站的 教程

爬取规则

  1. 你应该在爬取以前先检查一下网站使用条款。仔细的阅读其中关于合法使用数据的声明。通常来讲,你爬取的数据不能用于商业用途。
  2. 你的爬取程序不要太有攻击性地从网站请求数据(就像众所周知的垃圾邮件攻击同样),那可能会对网站形成破坏。确保你的爬虫程序以合理的方式运行(如同一我的在操做网站那样)。一个网页每秒请求一次是个很好的作法。
  3. 网站的布局时不时的会有变化,因此要确保常常访问网站而且必要时及时重写你的代码。

检查网页

让咱们以 Bloomberg Quote 网站的一个页面为例。

由于有些人会关注股市,那么咱们就从这个页面上获取指数名称(标准普尔 500 指数)和它的价格。首先,从鼠标右键菜单中点击 Inspect 选项来查看页面。

试着把鼠标指针悬浮在价格上,你应该能够看到出现了一个蓝色方形区域包裹住了价格。若是你点击,在浏览器的控制台上,这段 HTML 内容就被选定了。

经过结果,你能够看到价格被好几层 HTML 标签包裹着,<div class="basic-quote"><div class="price-container up"><div class="price">

相似的,若是你悬浮而且点击“标准普尔 500 指数”,它被包裹在 <div class="basic-quote"><h1 class="name"> 里面。

如今咱们经过 class 标签的帮助,知道了所需数据的确切位置。

编写代码

既然咱们知道数据在哪儿了,咱们就能够编写网页爬虫了。如今打开你的文本编辑器。

首先,须要导入全部咱们须要用到的库。

# import libraries
import urllib2
from bs4 import BeautifulSoup
复制代码

接下来,声明一个网址连接变量。

# specify the url
quote_page = ‘http://www.bloomberg.com/quote/SPX:IND'
复制代码

而后,使用 Python 的 urllib2 来请求声明的 url 指向的 HTML 网页。

# query the website and return the html to the variable ‘page’
page = urllib2.urlopen(quote_page)
复制代码

最后,把页面内容解析成 BeatifulSoup 的格式,以便咱们可以使用 BeautifulSoup 去处理。。

# parse the html using beautiful soup and store in variable `soup`
soup = BeautifulSoup(page, ‘html.parser’)
复制代码

如今咱们有一个变量 soup,它包含了页面的 HTML 内容。这里咱们就能够编写爬取数据的代码了。

还记得数据的独特的层级结构吗?BeautifulSoup 的 find() 方法能够帮助咱们找到这些层级结构,而后提取内容。在这个例子中,由于这段 HTML 的 class 名称是惟一的,全部咱们很容易找到 <div class="name">

# Take out the <div> of name and get its value
name_box = soup.find(‘h1’, attrs={‘class’: ‘name’})
复制代码

咱们能够经过获取标签的 text 属性来获取数据。

name = name_box.text.strip() # strip() is used to remove starting and trailing
print name
复制代码

相似地,咱们也能够获取价格。

# get the index price
price_box = soup.find(‘div’, attrs={‘class’:’price’})
price = price_box.text
print price
复制代码

当你运行这个程序,你能够看到标准普尔 500 指数的当前价格被打印了出来。

输出到 Excel CSV

既然咱们有了数据,是时候去保存它了。Excel 的 csv 格式是一个很好的选择。它能够经过 Excel 打开,因此你能够很轻松的打开并处理数据。

可是,首先,咱们必须把 Python csv 模块导入进来,还要导入 datetime 模块来获取记录的日期。在 import 部分,加入下面这几行代码。

import csv
from datetime import datetime
复制代码

在你的代码底部,添加保存数据到 csv 文件的代码。

# open a csv file with append, so old data will not be erased
with open(‘index.csv’, ‘a’) as csv_file:
 writer = csv.writer(csv_file)
 writer.writerow([name, price, datetime.now()])
复制代码

若是你如今运行你的程序,你应该能够导出一个index.csv文件,而后你能够用 Excel 打开它,在里面能够看到一行数据。

若是你天天运行这个程序,你就能够很简单地获取标准普尔 500 指数,而不用重复地经过网页查找。

进阶使用 (高级应用)

多个指数
对你来讲,只获取一个指数远远不够,对不对?咱们能够同时提取多个指数。

首先,将 quote_page 变量修改成一个 URL 的数组。

quote_page = [‘http://www.bloomberg.com/quote/SPX:IND', ‘http://www.bloomberg.com/quote/CCMP:IND']
复制代码

而后咱们把数据提取代码变成 for 循环,这样能够一个接一个地处理 URL,而后把全部的数据都存到元组 data 中。

# for loop
data = []
for pg in quote_page:
 # query the website and return the html to the variable ‘page’
 page = urllib2.urlopen(pg)

# parse the html using beautiful soap and store in variable `soup`
 soup = BeautifulSoup(page, ‘html.parser’)

# Take out the <div> of name and get its value
 name_box = soup.find(‘h1’, attrs={‘class’: ‘name’})
 name = name_box.text.strip() # strip() is used to remove starting and trailing

# get the index price
 price_box = soup.find(‘div’, attrs={‘class’:’price’})
 price = price_box.text

# save the data in tuple
 data.append((name, price))
复制代码

而后,修改“保存部分”的代码以逐行保存数据。

# open a csv file with append, so old data will not be erased
with open(‘index.csv’, ‘a’) as csv_file:
 writer = csv.writer(csv_file)
 # The for loop
 for name, price in data:
 writer.writerow([name, price, datetime.now()])
复制代码

从新运行代码,你应该能够同时提取到两个指数了。

高级的爬虫技术

BeautifulSoup 是一个简单且强大的小规模的网页爬虫工具。可是若是你对更大规模的网络数据爬虫感兴趣,那么你应该考虑使用其余的替代工具。

  1. Scrapy,一个强大的 Python 爬虫框架
  2. 尝试将你的代码与一些公共 API 集成。数据检索的效率要远远高于网页爬虫的效率。好比,看一下 Facebook Graph API,它能够帮助你获取未在 Facebook 网页上显示的隐藏数据。
  3. 若是爬取数据过大,请考虑使用一个后台数据库来存储你的数据,好比 MySQL

采用 DRY 方法

DRY(Don't Repeat Yourself)表明“不要重复本身的工做”,尝试把你每日工做都自动化,像 这我的 作的那样。能够考虑一些有趣的项目,多是跟踪你的 Facebook 好友的活跃时间(须要得到他们的赞成),或者是获取论坛的演讲列表并尝试进行天然语言处理(这是当前人工智能的一个热门话题)!

若是你有任何问题,能够随时在下面留言。

参考:

这篇文章最初发表在 Altitude Labs博客上,做者是咱们的软件工程师 Leonard MokAltitude Labs 是一家专门从事 React 移动应用定制开发的软件代理商。

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索