本教程系列旨在教授如何从网站中提取数据。大多数网站数据以HTML格式存在,因此第一个教程解释了这种标记语言的基础知识。第二个指南展示了如何使用一个直观的网页抓取工具来轻松抓取数据,无需了解HTML。而最后几个教程则专注于使用Python从网页中收集数据。在这种情况下,需要直接与HTML页面交互,并需要一些HTML的先验知识。
网页数据提取是收集网页数据并将其存储在结构化格式中的过程,例如CSV文件。例如,如果想预测亚马逊产品评论的评分,可能会对在官方网站上收集该产品的信息感兴趣。
当然不能从所有网站抓取数据。建议首先查看robots.txt文件以避免法律问题。只需要在URL末尾添加'/robots.txt'来检查网站允许/不允许的部分。
以一个例子为例,将使用两个Python库,Requests和Beautiful Soup,从维基百科中提取按温室气体排放量排列的国家列表,就像本系列教程中的前几个教程一样。
教程的第一步是检查是否安装了所有必需的库:
!pip install beautifulsoup4
!pip install requests
一旦完成查看,需要导入库:
from bs4 importBeautifulSoup
import requests
import pandas as pd
Beautiful Soup是一个有用的库,用于从HTML和XML文件中提取数据。它为解析页面构建了一种解析树。实际上,HTML文档由标签树组成。将展示一个HTML代码示例,以帮助理解这个概念。
<!DOCTYPE html>
<html>
<head>
<title>网页抓取教程</title>
</head>
<body>
<h1>1. 导入库</h1>
<p>让导入:</p>
</body>
</html>
由于HTML具有树状结构,因此也有祖先、后代、父级、子级和兄弟级。
要获取网页,第一步是创建一个响应对象,将URL传递给get方法。
url = 'https://en.wikipedia.org/wiki/List_of_countries_by_greenhouse_gas_emissions'
req = requests.get(url)
print(req)
# <Response[200]>
请求-响应协议。
让创建Beautiful Soup对象,它使用HTML解析器解析文档。通过这种方式,将HTML代码转换为Python对象树,就像之前在插图中展示的那样。
soup =BeautifulSoup(req.text,"html.parser")
print(soup)
如果打印对象,将看到网页的所有HTML代码。
正如观察到的,这棵树包含许多标签,这些标签包含不同类型的信息。可以直接访问标签,只需编写:
soup.head
soup.body
soup.body.h1
# <h1 class="firstHeading" id="firstHeading">按温室气体排放量排列的国家列表</h1>
更有效的方式是使用find和find_all方法,这些方法过滤元素(在find_all方法的情况下)。
row1 = tab.find('tr')
print(row1)
使用find方法,放大文档的一部分,这些标签用于构建表格的每一行。在这种情况下,只得到了第一行,因为该函数只提取一个元素。相反,如果想要收集表格的所有行,使用另一种方法:
rows = tab.find_all('tr')
print(len(rows))
print(rows[0])
获得了一个包含187个元素的列表。如果显示第一项,将看到与之前相同的输出。
要存储所有元素,创建一个字典,它将只包含列名作为键和空列表作为值。
rows = tab.find_all('tr')
cols = [t.text.rstrip() for t in rows[0].find_all('th')]
diz = {c:[] for c in cols}
表格的第一行只包含标题,其余行构成主体。要查看特定元素的HTML代码,需要将鼠标指针放在该点上,并右键单击“检查”。
因此,遍历表格的行,不包括第一行:
for r in rows[1:]:
diz[cols[0]].append(r.find('th').text.
replace('xa0', '').rstrip())
row_other = r.find_all('td')
for idx,c in enumerate(row_other):
cell_text = c.text.replace('xa0', '').rstrip()
diz[cols[idx+1]].append(cell_text)
df = pd.DataFrame(diz)
df.head()
df.to_csv('tableghg.csv')