【问题标题】:Web scraping both html text and image link with Python Beautifulsoup使用 Python Beautifulsoup 抓取 html 文本和图像链接的网页
【发布时间】:2018-01-21 01:51:16
【问题描述】:

我是 Python 新手,想使用 BeautifulSoup 从这个 URL 中抓取表格:http://www.espn.com/college-sports/basketball/recruiting/databaseresults?firstname=&lastname=&class=2007&starsfilter=GT&stars=0&ratingfilter=GT&rating=&positionrank=&sportid=4294967265&collegeid=&conference=&visitmonth=&visityear=&statuscommit=Commitments&statusuncommit=Uncommited&honor=&region=&state=&height=&weight=

到目前为止,我已经弄清楚了如何提取每个玩家所在行的表格数据,以及每行中学校徽标的链接。但是,我很难将两者结合起来。我想提取每个玩家的表格数据(下面代码中的player_data)以及他们相应的学校徽标图片链接(logo_links),并在保存的 CSV 中将每个玩家的数据放入一行。

以下是我目前所拥有的。提前感谢您的帮助。

#! python3
# downloadRecruits.py - Downloads espn college basketball recruiting database info

import requests, os, bs4, csv
import pandas as pd

# Starting url (class of 2007)
url = 'http://www.espn.com/college-sports/basketball/recruiting/databaseresults?firstname=&lastname=&class=2007&starsfilter=GT&stars=0&ratingfilter=GT&rating=&positionrank=&sportid=4294967265&collegeid=&conference=&visitmonth=&visityear=&statuscommit=Commitments&statusuncommit=Uncommited&honor=&region=&state=&height=&weight='


# Download the page
print('Downloading page %s...' % url)
res = requests.get(url)
res.raise_for_status()

# Creating bs object
soup = bs4.BeautifulSoup(res.text, "html.parser")

# Get the data
data_rows = soup.findAll('tr')[1:]
type(data_rows)

player_data = [[td.getText() for td in data_rows[i].findAll('td')] for i in range(len(data_rows))]

logo_links = [a['href'] for div in soup.find_all("div", attrs={"class": "school-logo"}) for a in div.find_all('a')]


# Saving only player_data
with open('recruits2.csv', 'w') as f_output:
   csv_output = csv.writer(f_output)
   csv_output.writerows(player_data)

【问题讨论】:

  • list(zip(player_data, logo_links)) 是你想要的吗?
  • @ViníciusAguiar 这很好地排列了两个列表,但我希望logo_links 成为player_data 的同一列表的一部分。当我按照您的建议压缩列表后导出到 CSV 时,所有player_data 都在一个列中,然后logo_links 在第二列中:d1ax1i5f2y3x71.cloudfront.net/items/2817413i333G1A3k1N44/…。我的理想输出是 CSV,其中有一列与现有表的每个列匹配。

标签: python web-scraping beautifulsoup


【解决方案1】:

我会做这样的事情。
原因 1:您不必在 HTML 中查找两次内容。
原因 2:按照原因 1,您不必再次运行循环。

player_data = []
for tr in data_rows:
    tdata = []
    for td in tr:
        tdata.append(td.getText())

        if td.div and td.div['class'][0] == 'school-logo':
            tdata.append(td.div.a['href'])

    player_data.append(tdata)

小解释-
主要是,我没有使用列表解析,因为 if 块在 HTML 中查找具有所需类名的 div 块,如果确实如此,它会附加到它在 @ 中收集的数据列表中987654325@标签。

【讨论】:

    【解决方案2】:

    要将logo_links 元素附加到player_data 内的每个列表中,您可以执行以下操作:

    >>> i = 0
    >>> for p in player_data:
        p.append(logo_links[i])
        i+=1
    

    【讨论】:

    • 效果很好!谢谢你。正如我正在学习的那样,你有没有机会解释为什么会这样?主要是p这里是什么?
    • 很高兴为您提供帮助!在 Python 中,您可以执行 for 循环来迭代任何 iterable 的元素,例如列表或字符串。然后将序列中的第一项(在本例中为 player_data)分配给您的变量(在本例中为 p),并且每次循环时,它都会分配给下一个值。尝试在循环内写print(p),你会更好地看到它是如何进行的。 Here 是一个很好的参考。
    • 这是有道理的。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    相关资源
    最近更新 更多