本系列教程旨在教授如何从网站中提取数据。大多数网站数据以HTML格式存在,因此第一篇教程解释了这种标记语言的基础知识。第二篇指南展示了如何使用直观的网页抓取工具轻松抓取数据,无需了解HTML。第三篇也是最后一篇教程则专注于使用Python从网络中收集数据。在这种情况下,需要直接与HTML页面交互,并且需要一些HTML的先验知识。
近年来,网络上可用数据的指数增长导致了对网页抓取的需求。网页抓取是什么?它提供了一套技术,用于从网页中提取和处理大量数据。为了从网站收集信息,有许多可能的抓取工具可以应用。
在本教程中,将专注于使用Selenium进行网页抓取。特别是,它将用于从维基百科页面中收集和解析HTML代码,即按温室气体排放量排列的国家列表。Selenium爬虫支持许多语言,包括本教程中使用的Python。
在开始本教程之前,需要在计算机上安装Python3。使用Jupiter笔记本在Windows 10上编写代码。要安装Selenium,只需在笔记本中复制以下行:
!pip install selenium
之后,需要安装一个浏览器驱动程序,这取决于经常使用的浏览器。在情况下,使用Chrome,因此安装了Chrome驱动程序。以下是一些流行浏览器驱动程序的链接:
ChromeDriver - Chrome的WebDriver
Microsoft Edge Driver - 微软Edge的WebDriver
GeckoDriver - Firefox的WebDriver
Safari的WebDriver支持
在这里,展示了Selenium的方法来查找网页中的多个元素。然后,这些方法返回列表。
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
要定位网站上的一个元素,有相应的方法:
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
只需要从元素字符串中移除‘s’。在本指南中,使用find_elements_by_class_name,需要知道HTML代码中所选标签的类名,以及find_elements_by_xpath,它使用XPath指定元素的路径。
XPath是一种语言,它使用路径表达式来获取XML文档中的节点或一组节点。这与通常在计算机文件系统中看到的路径相似。最有用的路径表达式包括:
nodename - 获取该名称的节点
/ - 从根节点获取
// - 从当前节点获取文档中的节点
. - 获取当前节点
.. - 获取当前节点的“父节点”
@ - 获取该节点的属性,例如id和class
要更好地理解XPath,请查看w3schools网站。
让从导入库开始:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import pandas as pd
首先,创建一个Chrome WebDriver的实例,指定已安装的Chromedriver的路径:
driver = webdriver.Chrome(r"C:UsersEugeniaDownloadschromedriver_win32chromedriver.exe")
给定URL,使用driver.get导航到网页。
url = 'https://en.wikipedia.org/wiki/List_of_countries_by_greenhouse_gas_emissions'
driver.get(url)
感兴趣的是从表格中提取数据,将其保存在Pandas DataFrame中,并将其导出为CSV文件。
第一步是提取表格的标题行。如前所示,find_elements_by_class_name只需要类名作为输入。
titles = driver.find_elements_by_class_name('headerSort')
for t in titles:
print(t.text)
通过这种方式,获得了一个包含表格所有标题的列表。已经可以创建一个空的DataFrame,并指定列的名称。
df = pd.DataFrame(columns=[t.text for t in titles])
df.head()
现在,是时候收集每个列中包含的数据了。如所见,标签包含HTML表格的主体内容,因此想要提取的所有单元格都在这些标签内。
states = driver.find_elements_by_xpath('//table[@class="wikitable sortable plainrowheaders jquery-tablesorter"]/tbody/tr/th')
要检查找到的状态,打印列表:
for idx, s in enumerate(states):
print('row {}:'.format(idx))
print('{}'.format(s.text))
col2 = driver.find_elements_by_xpath('//table[@class="wikitable sortable plainrowheaders jquery-tablesorter"]/tbody/tr/td[1]')
col3 = driver.find_elements_by_xpath('//table[@class="wikitable sortable plainrowheaders jquery-tablesorter"]/tbody/tr/td[2]')
col4 = driver.find_elements_by_xpath('//table[@class="wikitable sortable plainrowheaders jquery-tablesorter"]/tbody/tr/td[3]')
col5 = driver.find_elements_by_xpath('//table[@class="wikitable sortable plainrowheaders jquery-tablesorter"]/tbody/tr/td[4]')
df[df.columns[0]] = [s.text for s in states]
df[df.columns[1]] = [s.text for s in col2]
df[df.columns[2]] = [s.text for s in col3]
df[df.columns[3]] = [s.text for s in col4]
df[df.columns[4]] = [s.text for s in col5]
df.head()
df.to_csv('greenhouse_gas_emissions.csv')