【问题标题】:Scraping multiple pages with Python Beautifulsoup -- only returning data from last page使用 Python Beautifulsoup 抓取多个页面——只返回最后一页的数据
【发布时间】:2018-01-28 05:39:29
【问题描述】:

我正在尝试遍历多个页面以使用 Python 和 Beautifulsoup 抓取数据。我的脚本适用于一个页面,但是当尝试遍历多个页面时,它只返回最后一页抓取的数据。我认为我循环或存储/附加player_data 列表的方式可能有问题。

这是我迄今为止所得到的——非常感谢任何帮助。

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

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

# Starting url (class of 2007)
base_url = 'http://www.espn.com/college-sports/basketball/recruiting/databaseresults/_/class/2007/page/'

# Number of pages to scrape (Not inclusive, so number + 1)
pages = map(str, range(1,3))

# url for starting page
url = base_url + pages[0]

for n in pages:
    # Create url
    url = base_url + n

    # Parse data using BS
    print('Downloading page %s...' % url)
    res = requests.get(url)
    res.raise_for_status()

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

    table = soup.find('table')

    # Get the data
    data_rows = soup.findAll('tr')[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)

print(player_data)

【问题讨论】:

  • print(player_data)前加4个空格

标签: python web-scraping beautifulsoup


【解决方案1】:

您应该将player_data 列表定义放在循环之外,否则只会存储最后一次迭代的结果。

【讨论】:

  • 感谢@Kostas Drk。问题——这也适用于保存到 CSV 吗?当我用以下内容替换 print(player_data) 时,它只保存最后一页: with open('bballRecruits.csv', 'w') as f_output: csv_output = csv.writer(f_output) csv_output.writerows(player_data)跨度>
  • @NateRattner 是的,无论你如何处理该列表,都取决于其中存储的内容。
【解决方案2】:

这是缩进问题或声明问题,取决于您期望的结果。

  • 如果需要打印每一页的结果:

您可以通过在 print(player_data) 前添加 4 个空格来解决此问题。

如果你让 print 语句在 for 循环块之外,它只会在循环结束后执行一次。所以它可以显示的唯一值是从 for 循环的最后一次迭代中泄漏的 player_data 的最后一个值。

  • 如果您想将所有结果存储在player_data 并在最后打印出来:

您必须在 for 循环之外和之前声明 player_data

player_data = []
for n in pages:
    # [...]

【讨论】:

  • OP 询问返回的数据,而不仅仅是打印的内容。
  • 谢谢@PRMoureu。我应该更清楚——我确实想将所有结果存储在 player_data 中,然后在最后打印出来。所以这是完美的。
【解决方案3】:
import requests
from bs4 import BeautifulSoup

# Starting url (class of 2007)
base_url = 'http://www.espn.com/college-sports/basketball/recruiting/databaseresults/_/class/2007/page/'

# Number of pages to scrape (Not inclusive, so number + 1)
pages = list(map(str,range(1,3)))
# In Python 3, map returns an iterable object of type map, and not a subscriptible list, which would allow you to write map[i]. To force a list result, write
# url for starting page
url = base_url + pages[0]

for n in pages:
    # Create url
    url = base_url + n

    # Parse data using BS
    print('Downloading page %s...' % url)
    res = requests.get(url)
    res.raise_for_status()

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

    table = soup.find('table')

    # Get the data
    data_rows = soup.findAll('tr')[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)

print(player_data)

【讨论】:

    猜你喜欢
    • 2014-12-17
    • 1970-01-01
    • 2019-07-18
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多