查看原文
其他

3步走方略——用Python为数据科学项目收集数据

数据应用学院 大数据应用 2023-08-17

今日份知识你摄入了么?

每个数据科学项目都需要数据,因此我们使用网页爬取工具从网页中爬取数据并构建我们的数据集。


问题是,一个网页的数据可能并不齐全,无法满足我们所需,或者它可能有一些不一致性,导致我们只爬取了一部分数据。



当我从世界杯网页上爬取1930到2022的足球比赛时(https://medium.com/geekculture/web-scraping-football-matches-from-the-world-cups-1930-to-2022-with-python-d2a1d578f034),这种情况就发生在我身上了。我只爬取了部分数据,而不是全部。在这篇文章中,我们将使用Selenium从头开始爬取剩余的足球比赛数据,以便稍后在项目中使用这些数据(https://frank-andrade.medium.com/list/python-project-fifa-world-cup-2022-prediction-85426e7c421c)


步骤1:

安装Selenium


要安装Selenium,请打开一个终端并运行以下命令。


pip install selenium


现在我们需要为我们的电脑下载正确版本的Chrome驱动。


  1. 检查你的Google Chrome版本(在Chrome上点击“…”,点击“帮助”,然后点击“about Google Chrome”)

  2. 在此处下载正确的Chrome驱动版本(https://chromedriver.chromium.org/downloads)(在Chrome更新后,你需要再次下载文件)

  3. 解压下载的文件,并将路径复制到你要保留的Chrome驱动文件的位置。


步骤2:

爬取数据


要从网页中爬取数据,首先,我们必须导入所有要使用的库。


from selenium import webdriverfrom selenium.webdriver.chrome.service import Serviceimport timeimport pandas as pd


  • Selenium:帮助我们收集数据的库

  • Time:帮助我们添加自动化网页时的等待时间

  • Pandas:帮助我们将爬取的数据组成数据帧


每次我们用Selenium爬取网页数据时,我们必须定义以下变量:


  • 路径:你的Chrome驱动文件所在的位置

  • 网页:我们要爬取的网页

    (我们将爬取此页面:https://en.wikipedia.org/wiki/1982_FIFA_World_Cup)

  • 驱动:帮助我们爬取网页所需数据


path = # Write your path hereservice = Service(executable_path=path)driver = webdriver.Chrome(service=service)web = 'https://en.wikipedia.org/wiki/1982_FIFA_World_Cup'


现在打开Chrome驱动并转到目标网页,我们运行以下代码。


driver.get(web)


系统将弹出一个新窗口,上面显示“Chrome is controlled by automated test software”



现在,我们必须查看我们希望爬取的元素隐藏的HTML代码。然后,我们向下滚动,直到找到足球比赛,然后右键单击并选择“Inspect”。


然后,调试工具将被打开。我们单击“select button”(左侧的光标),然后找到包含足球比赛的那一行。



选定该行后,我们将获得其HTML元素。


<tr style="font-size:90%">


现在,要使用Selenium定位该元素,我们必须创建它的XPath。下面是XPath的句法。



如果我们替换每个元素,我们会得到:


//tr[@style="font-size:90%"]


一旦创建了XPath,我们就可以使用.find_elements通过Selenium来定位这样的元素。


matches = driver.find_elements(by='xpath', value='//tr[@style="font-size:90%"]')


我们的变量matches包含网页上列出的48行/匹配项。如果我们循环浏览列表,我们可以获取所有的td元素,因为它们是我们之前创建的XPath的tr元素的子节点。



td元素包含home(主场球队)、score(比分)和away(客场球队)。我们可以通过以下XPath获得这些数据。


/td[1]:home team/td[2]:score/td[3]:away team


让我们循环浏览matches,并将数据存储在我命名为home,score和away的空列表中。


home = []score = []away = []for match in matches:    home.append(match.find_element(by='xpath', value='./td[1]').text)    score.append(match.find_element(by='xpath', value='./td[2]').text)    away.append(match.find_element(by='xpath', value='./td[3]').text)


要注意,我在源XPath/td前加入了“.”,因为现在我们使用的不是driver.find_element而是match.find_element(“.”表示我们从匹配节点开始搜索)


除此之外,我们还添加了text属性以获取节点内的文本(例如,英国3-1法国)


最后,我们从home、score和away列表中创建一个数据帧。我们添加一个新的year 列,等待2秒(这是可选的),然后退出driver。


dict_football = {'home': home, 'score': score, 'away': away}df_football = pd.DataFrame(dict_football)df_football['year'] = 1982time.sleep(2)driver.quit()


要导出数据帧,我们使用.to_csv.。


df_football.to_csv("fifa_worldcup_missing_data.csv", index=False)


导出的数据应如下图所示,具有48行。



目前编写的代码可以在我的GitHub上找到(https://github.com/ifrankandrade/fifa-world-cup-2022-prediction)。现在,让我们稍微调整一下代码,试着爬取更多的网页页面。


步骤3:

创建一个函数来爬取多个页面


网页爬取最酷的是,一旦我们爬取了一个页面,我们就可以从同一个网页爬取多个页面(只要它们具有相同的结构)


下面是完成这项工作的函数。


def get_misssing_data(year):    web = f'https://en.wikipedia.org/wiki/{year}_FIFA_World_Cup'    driver.get(web)    matches = driver.find_elements(by='xpath', value='//tr[@style="font-size:90%"]')    home = []    score = []    away = []    for match in matches:        home.append(match.find_element(by='xpath', value='./td[1]').text)        score.append(match.find_element(by='xpath', value='./td[2]').text)        away.append(match.find_element(by='xpath', value='./td[3]').text)    dict_football = {'home': home, 'score': score, 'away': away}    df_football = pd.DataFrame(dict_football)    df_football['year'] = year    time.sleep(2)    return df_football


请注意,此函数使用year作为输入。我把这个year变量放到web的链接和df_football[‘year’]列中。其余的保持不变。


如果我们运行get_misssing_data(1982),我们将得到与步骤2中相同的输出。


为了从多个页面中爬取数据,我们创建一个years列表,其中包含世界杯举办的所有年份。


years = [1930, 1934, 1938, 1950, 1954, 1958, 1962, 1966, 1970, 1974,         1978, 1982, 1986, 1990, 1994, 1998, 2002, 2006, 2010, 2014,         2018]


现在,我们将使用列表推导来删除与每年相对应的页面,并将数据保存在名为fifa的列表中。我们将所有列表与.concat放在一起,最后将此数据导出为CSV。


fifa = [get_misssing_data(year) for year in years]driver.quit()df_fifa = pd.concat(fifa, ignore_index=True)df_fifa.to_csv("fifa_worldcup_missing_data.csv", index=False)


现在,我们的CSV文件应该有数百行,其中包含爬取的所有数据。



恭喜!现在你已经知道了如何使用Selenium构建数据集。你可以使用我们在此项目中爬取的数据集:https://frank-andrade.medium.com/list/python-project-fifa-world-cup-2022-prediction-85426e7c421c

原文作者:Frank Andrade

翻译作者:高佑兮

美工编辑:过儿

校对审稿:Chuang

原文链接:https://medium.com/geekculture/how-to-collect-data-for-a-data-science-project-with-python-in-3-steps-40effa214aea


本周公开课预告

往期精彩回顾

2022年IDEAS全球人工智能大会火热抢票中!

关于开发Open-Source,我学到的6个教训!

使用SQL总结A/B实验结果

认识Julia:数据科学的未来

招贤纳士 | Marketing specialist、Business Development Manager






点「在看」的人都变好看了哦

点击“阅读原文”查看数据应用学院核心课程

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存