【问题标题】:I'm trying to web scrape a webpage and store the data in a CSV file. But I can't seem to get my code to work我正在尝试网页抓取网页并将数据存储在 CSV 文件中。但我似乎无法让我的代码工作
【发布时间】:2019-07-01 17:23:29
【问题描述】:

我正在尝试从此链接中抓取网页,https://www.premierleague.com/stats/top/players/goals?se=-1 而且我似乎没有成功。

下面是我试过的代码。

from urllib.request import urlopen
from bs4 import BeautifulSoup
import requests
import csv`

url = "https://www.premierleague.com/stats/top/players/goals?se=-1"
html = urlopen(url)
bs = BeautifulSoup(html, 'html.parser')

#print(bs)

listings = []

for rows in bs.find_all("tr"):
 if("oddrow" in rows["class"]) or ("evenrow" in rows["class"]):
    name = rows.find("div", class_="playerName").a.get_text()
    country = rows.find_all("td")[1].get_text()
    goals = rows.find_all("td")[4].get_text()
    listings.append([name, country, goals])

with open("EPL_TEST.csv", 'a', encoding = 'utf-8') as toWrite:
    writer = csv.writer(toWrite)
    writer.writerows(listings)

print("Data Fetched")

这是我得到的错误:C:\Users\Siddhardh\Desktop\Python\Projects\FinalProject\venv\Scripts\python.exe C:/Users/Siddhardh/Desktop/Python/Projects/FinalProject/Scraping.py Traceback (most recent call last): File "C:/Users/Siddhardh/Desktop/Python/Projects/FinalProject/Scraping.py", line 16, in <module> if("oddrow" in rows["class"]) or ("evenrow" in rows["class"]): File "C:\Users\Siddhardh\Desktop\Python\Projects\FinalProject\venv\lib\site-packages\bs4\element.py", line 1016, in __getitem__ return self.attrs[key] KeyError: 'class'

Process finished with exit code 1

我需要将所有球员的姓名、国家和目标放入 CSV 文件中。

附:请原谅我的编辑技巧。这是我在这里的第一篇文章。我会学习的。

【问题讨论】:

  • 您查看过@Siddarth Krishna S 的任何一个答案吗?人们花时间解决问题,所以尽量不要无动于衷。谢谢。
  • 对不起。是的,人们一直乐于助人。我刚出城,没有带笔记本电脑。刚回来看看这些 cmets。

标签: python web-scraping


【解决方案1】:

尝试下面的脚本来获取遍历多个页面的所有名称以及包含数据的 csv 文件。您可以使用 chrome 开发工具获取我在脚本中使用的链接。使用该链接,您将获得 json 响应。修改以获取所有其他字段。

import csv
import requests
from bs4 import BeautifulSoup

url = "https://footballapi.pulselive.com/football/stats/ranked/players/goals?page={}&pageSize=20&comps=1&compCodeForActivePlayer=EN_PR&altIds=true"

headers = {
    'Origin': 'https://www.premierleague.com',
}

def get_items(link,page):
    while True:
        res = requests.get(link.format(page),headers=headers)
        soup = BeautifulSoup(res.text,"lxml")
        if not len(res.json()['stats']['content']):break
        for item in res.json()['stats']['content']:
            player_name = item['owner']['name']['display']
            yield player_name

        page+=1

if __name__ == '__main__':
    page = 112
    with open("player_info.csv","w", newline="") as outfile:
        writer = csv.writer(outfile)
        writer.writerow(['page','player'])
        for name in get_items(url,page):
            writer.writerow([name])

我使用page = 112 从该页面获取所有名称。随意将其设为0 以获取从头到尾的名称。

【讨论】:

  • 是的。这就是我需要它的方式,并且您的代码可以正常工作。但我的 CSV 只包含一页。我需要跨多个页面执行此操作,并尝试循环删除。没有成功。
  • 所以我修改了国家和目标,然后像您在原始回复中所做的那样添加到 CSV,对吧?
  • 它似乎不起作用。你能帮我解决吗?
  • 不清楚doesn't seem to be working 是什么意思,因为我发现它以正确的方式工作@Siddarth Krishna S.
  • 你是否得到了所有超过第 1 页的球员的名字?
【解决方案2】:

看来您必须将代码的中间部分更改为:

listings = []

names = bs.find_all("td",scopr="row")
countries = bs.find_all("span",  {"class": "playerCountry"})
goals = bs.find_all("td",class_="mainStat")
for name, country, goal in zip(names,countries,goals):    
    listings.append([name.text.strip(), country.text.strip(), goal.text.strip()])

打印出listings 会产生以下输出:

['艾伦希勒','英格兰','260'] ['韦恩鲁尼','英格兰','208'] ['安德鲁科尔','英格兰','187']

等等

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多