【发布时间】:2020-07-27 16:21:15
【问题描述】:
我有关于 for 循环的查询,并将其添加到已经工作的网络爬虫以运行网页列表。我看的大概是两三行简单的代码。
我很感激这个问题之前可能已经被问过很多次并得到了回答,但我一直在努力让一些代码为我工作很长一段时间了。我对 Python 比较陌生,并且希望改进。
背景信息:
我使用 Python 和 Beautifulsoup 编写了一个网络抓取工具,它能够成功地从 TransferMarkt.com 获取网页并抓取所有必需的网络链接。脚本由两部分组成:
- 在第一部分中,我将网页用于足球联赛, 例如英超联赛,并提取所有的网页链接 排名表中的各个团队,并将其放入列表中。
- 在我的脚本的第二部分中,我将这个单独的团队列表,并进一步提取每个团队的每个单独球员的信息,然后将它们连接在一起,形成一个球员信息的大熊猫 DataFrame。
我的问题是关于如何在这个网络爬虫的第一部分添加一个 for 循环,不仅可以从一个联赛网页中提取球队链接,还可以从联赛网页列表中提取链接。
下面我包含了一个足球联赛网页的示例、我的网络爬虫代码和输出。
示例:
要抓取的示例网页(英超联赛 - 代码 GB1):https://www.transfermarkt.co.uk/jumplist/startseite/wettbewerb/gb1/plus/?saison_id=2019
代码(第 1 部分,共 2 部分)- 从联赛网页上抓取各个球队的链接:
# Python libraries
## Data Preprocessing
import pandas as pd
## Data scraping libraries
from bs4 import BeautifulSoup
import requests
# Assign league by code, e.g. Premier League = 'GB1', to the list_league_selected variable
list_league_selected = 'GB1'
# Assign season by year to season variable e.g. 2014/15 season = 2014
season = '2019'
# Create an empty list to assign these values to
team_links = []
# Web scraper script
## Process League Table
headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}
page = 'https://www.transfermarkt.co.uk/jumplist/startseite/wettbewerb/' + id + '/plus/?saison_id=' + season
tree = requests.get(page, headers = headers)
soup = BeautifulSoup(tree.content, 'html.parser')
## Create an empty list to assign these values to - team_links
team_links = []
## Extract all links with the correct CSS selector
links = soup.select("a.vereinprofil_tooltip")
## We need the location that the link is pointing to, so for each link, take the link location.
## Additionally, we only need the links in locations 1, 3, 5, etc. of our list, so loop through those only
for i in range(1,59,3):
team_links.append(links[i].get("href"))
## For each location that we have taken, add the website before it - this allows us to call it later
for i in range(len(team_links)):
team_links[i] = "https://www.transfermarkt.co.uk" + team_links[i]
# View list of team weblinks assigned to variable - team_links
team_links
输出:
从示例网页中提取的链接(示例网页共20个链接,仅显示4个):
team_links = ['https://www.transfermarkt.co.uk/manchester-city/startseite/verein/281/saison_id/2019',
'https://www.transfermarkt.co.uk/fc-liverpool/startseite/verein/31/saison_id/2019',
'https://www.transfermarkt.co.uk/tottenham-hotspur/startseite/verein/148/saison_id/2019',
'https://www.transfermarkt.co.uk/fc-chelsea/startseite/verein/631/saison_id/2019',
...,
'https://www.transfermarkt.co.uk/sheffield-united/startseite/verein/350/saison_id/2019']
使用此团队列表 - team_links,然后我可以使用以下代码进一步提取每个团队的所有球员的信息。从这个输出中,我可以创建一个包含所有玩家信息的 pandas DataFrame:
代码(第 2 部分,共 2 部分)- 使用 team_links 列表抓取个人球员信息:
# Create an empty DataFrame for the data, df
df = pd.DataFrame()
# Run the scraper through each of the links in the team_links list
for i in range(len(team_links)):
# Download and process the team page
page = team_links[i]
df_headers = ['position_number' , 'position_description' , 'name' , 'dob' , 'nationality' , 'value']
pageTree = requests.get(page, headers = headers)
pageSoup = BeautifulSoup(pageTree.content, 'lxml')
# Extract all data
position_number = [item.text for item in pageSoup.select('.items .rn_nummer')]
position_description = [item.text for item in pageSoup.select('.items td:not([class])')]
name = [item.text for item in pageSoup.select('.hide-for-small .spielprofil_tooltip')]
dob = [item.text for item in pageSoup.select('.zentriert:nth-of-type(4):not([id])')]
nationality = ['/'.join([i['title'] for i in item.select('[title]')]) for item in pageSoup.select('.zentriert:nth-of-type(5):not([id])')]
value = [item.text for item in pageSoup.select('.rechts.hauptlink')]
df_temp = pd.DataFrame(list(zip(position_number, position_description, name, dob, nationality, value)), columns = df_headers)
df = df.append(df_temp) # This last line of code is mine. It appends to temporary data to the master DataFrame, df
# View the pandas DataFrame
df
我的问题 - 添加一个 for 循环来遍历所有联赛:
我需要做的是在我的代码的第一部分替换分配给单个联赛代码的 list_league_selected 变量,而是使用 for 循环来遍历联赛代码的完整列表 - list_all_leagues。本次联赛代码列表如下:
list_all_leagues = ['L1', 'GB1', 'IT1', 'FR1', 'ES1'] # codes for the top 5 European leagues
我已经阅读了几个解决方案,但我很难让循环正常工作并将团队网页的完整列表附加到正确的部分。我相信我现在真的接近完成我的爬虫了,任何关于如何创建这个 for 循环的建议都将不胜感激!
提前感谢您的帮助!
【问题讨论】:
-
这里信息量很大,难道没有办法浓缩吗?我也不确定我是否理解您具体在努力解决的问题。
标签: python pandas dataframe web-scraping beautifulsoup