【问题标题】:How to scrape multiple pages trouble with loop?如何用循环刮掉多个页面的麻烦?
【发布时间】:2019-11-28 10:03:16
【问题描述】:

这是我只抓取一页的代码,但我有 11000 个。区别在于他们的身份。

https://www.rlsnet.ru/mkb_index_id_1.htm
https://www.rlsnet.ru/mkb_index_id_2.htm
https://www.rlsnet.ru/mkb_index_id_3.htm
....
https://www.rlsnet.ru/mkb_index_id_11000.htm

如何循环我的代码来抓取所有 11000 页?如此大量的页面甚至可能吗?可以将它们放入一个列表中,然后进行抓取,但如果有 11000 个,那将是很长的路要走。

import requests
from pandas import DataFrame
import numpy as np
import pandas as pd
from bs4 import BeautifulSoup

page_sc = requests.get('https://www.rlsnet.ru/mkb_index_id_1.htm')
soup_sc = BeautifulSoup(page_sc.content, 'html.parser')
items_sc = soup_sc.find_all(class_='subcatlist__item')
mkb_names_sc = [item_sc.find(class_='subcatlist__link').get_text() for item_sc in items_sc]
mkb_stuff_sce = pd.DataFrame(
    {
        'first': mkb_names_sc,
    })
mkb_stuff_sce.to_csv('/Users/gfidarov/Desktop/Python/MKB/mkb.csv')

【问题讨论】:

  • 简单,将循环计数器传递给 url:'https://www.rlsnet.ru/mkb_index_id_{}.htm'.format(i)

标签: python pandas web web-scraping beautifulsoup


【解决方案1】:

您可以像这样动态创建 url 字符串。您可能还希望在循环的每个其他迭代中使用时间延迟,以免被服务器阻塞。

import requests
from pandas import DataFrame
import numpy as np
import pandas as pd
from bs4 import BeautifulSoup


path_of_csv = '/Users/gfidarov/Desktop/Python/MKB/mkb.csv'

first_string = 'https://www.rlsnet.ru/mkb_index_id_'
third_string = '.htm'

df = pd.DataFrame(columns=['scraping results'])

try:
    for second_string in range(1, 11001):
        second_string = str(second_string)
        url = first_string + second_string + third_string
        page_sc = requests.get(url)
        soup_sc = BeautifulSoup(page_sc.content, 'html.parser')
        items_sc = soup_sc.find_all(class_='subcatlist__item')
        mkb_names_sc = [item_sc.find(class_='subcatlist__link').get_text() for item_sc in items_sc]
        df.append({'scraping results': mkb_names_sc}, ignore_index=True)

    df.to_csv(
        path_or_buf=path_of_csv
    )

except:
    # If it fails in the middle of the process, the results won't be lost
    path_of_csv = 'backup_' + path_of_csv
    df.to_csv(
        path_or_buf=path_of_csv 
    )
    print('Failed at index ' + second_string + '. Please start from here again by setting the beginning of the range to this index. A backup was made of the results that were already scraped. You may want to rename the backup to avoid overwriting in the next run.')

【讨论】:

  • 这样,您可以避免在抓取之前创建一个长列表。当然,发送大量请求的问题仍然存在。您可能想参考这个问题以获得可能的解决方案:stackoverflow.com/questions/43169900/…
  • 这两种方法对我来说都很好,它们可以完成他们的工作,但由于某些原因,它会覆盖我 csv 中的数据。如何避免覆盖数据?
  • 每次通话后是否要将数据保存到磁盘?您还将结果保存到 pandas DataFrame(或列表/数组),最后只保存到 csv。将 csv 更新 11'000 次需要一些时间,而且无论如何都不是好主意。我建议以下解决方案:您创建一个包含结果的列表 (result_list = []),并在每次调用/迭代后将 mkb_names_sc 对象放入列表中 (result_list.append(mkb_names_sc)。除此之外,您还可以使用错误捕获器,可确保在出现问题时您的数据不会丢失。我会尽快更新我的答案以使这一点更清楚。
  • 是的,它将数据保存到 DataFrame 我可以在 PyCharm 中看到所有输出,但在我的 csv 中看不到。我还想为 csv 创建一个循环,因此对于每个页面,它将数据存储到一个单独的 csv 中。但我认为这将花费我一整天的时间来首先阅读所有 11000 页并将它们存储到所有 csv 中。此外,并非所有页面都具有相似的结构。所以它并没有定义它们。好的,我会等你的。非常感谢。
  • 好吧,那就更好了,我确实非常感谢我希望我能解决我的问题,非常感谢我真的很感激
【解决方案2】:

我的方法很简单。我只是在循环上面的代码。

for i in range(1,11001):

    page_sc = requests.get('https://www.rlsnet.ru/mkb_index_id_{}.htm'.format(i))

    soup_sc = BeautifulSoup(page_sc.content, 'html.parser')
    items_sc = soup_sc.find_all(class_='subcatlist__item')
    mkb_names_sc = [item_sc.find(class_='subcatlist__link').get_text() for item_sc in items_sc]
    mkb_stuff_sce = pd.DataFrame(
        {
            'first': mkb_names_sc,
        })
    mkb_stuff_sce.to_csv('/Users/gfidarov/Desktop/Python/MKB/mkb.csv')

我所做的是,我使用 for 循环遍历代码,range() 函数正在生成 index 列表,我使用 format() 方法将其放入 url。

这应该像一个魅力。希望这会有所帮助:)

【讨论】:

  • 你让我这一天的人欣赏这一点。我刚刚意识到,并非所有来自 cite 的数据都只抓取那些具有相同结构的数据。但我认为我将为每个页面结构的每个场景创建多个循环
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多