【问题标题】:Skip a link from a list when scraping part with python使用 python 抓取部分时跳过列表中的链接
【发布时间】:2020-05-14 17:53:24
【问题描述】:

第一次在这里发帖,无数次遇到已经解决但无法解决的问题。

以下 while 循环旨在下载包含在 url 列表中的文本(示例中为 3)。它对所有链接都执行此操作,但示例中的第三个链接 (this) 需要很长时间。通过在浏览器中打开它,它看起来像是有许多 jpg 图像。 (txt 表示合并到 1 个文件中的多个文档;在这个具体示例中,一些文档是图像)。

由于前面的这些行,可以在文本中识别图像:

<DOCUMENT>
<TYPE>GRAPHIC
<SEQUENCE>7
<FILENAME>tex99-4_pg01.jpg
<DESCRIPTION>GRAPHIC
<TEXT>
begin 644 tex99-4_pg01.jpg

它们后面跟着这段代码:

end
</TEXT>
</DOCUMENT>

如果下载时间过长,有什么方法可以跳过该链接以使抓取工具更快?我希望将此代码应用于这些链接中的 320K,并希望找到一种方法来加快下载速度,而不是“剪切”我之后获得的 txt

这是我目前用来抓取的:

import pandas as pd
import requests

list_of_links = ['https://www.sec.gov/Archives/edgar/data/1000298/0001193125-14-321757.txt',  
                 'https://www.sec.gov/Archives/edgar/data/1002225/0000903423-14-000495.txt', 
                 'https://www.sec.gov/Archives/edgar/data/1004724/0001144204-14-042745.txt'] # the one with the images
number_of_urls = len(list_of_links)  # get number of links to iterate them
i = 0         

column_names = ["Filing text"]
DF = pd.DataFrame(columns = column_names)

while i < number_of_urls: 
    print("File #", i+1,"\tis being processed") # print this to visually see how long each download takes
    DF.loc[i, "Filing text"] = requests.get(list_of_links[i]).text
    i += 1

【问题讨论】:

  • 哦,伙计——不要像那样附加到你的数据框。实例化时延迟填充:pandas.DataFrame([requests.get(link).text for link in list_of_links], columns=columns_names)

标签: python pandas beautifulsoup


【解决方案1】:

对于requests库,你可以查看这个答案:https://stackoverflow.com/a/22347526/8294752

在您的情况下,由于它始终只是文本数据,因此查看内容长度就足够了。

另一方面,在请求调用中包含timeout 始终是一种很好的做法。这不会解决您的问题,因为超时仅考虑服务器不响应的时间,但没有它会产生问题,尤其是在循环中。

编辑

这可能是解决您的问题的有效解决方案(我也在这里合并了 Paul H 的反馈):

请注意,我交换了列表中的第二个和最后一个 URL,以便您更好地评估节省的时间。另外,请记住,如果末尾有 df,您将有一些 None,并根据您要下载的数据设置有意义的 CONTENT_LENGTH_LIMIT

import pandas as pd
import requests

list_of_links = ['https://www.sec.gov/Archives/edgar/data/1000298/0001193125-14-321757.txt',
                 'https://www.sec.gov/Archives/edgar/data/1004724/0001144204-14-042745.txt',  
                 'https://www.sec.gov/Archives/edgar/data/1002225/0000903423-14-000495.txt', 
                 ] # the one with the images     

column_names = ["Filing text"]
DF = pd.DataFrame(columns = column_names)

CONTENT_LENGTH_LIMIT = 8070869 # just a limit which is lower than the size of the third link
def fetch_text(url):
    print("Url", url,"\tis being processed") # print this to visually see how long each download takes
    try:
        r = requests.get(url, stream=True, timeout=5)
        if int(r.headers.get('Content-Length')) > CONTENT_LENGTH_LIMIT:
            print("Url", url,"\thas been skipped")
            return None
        else: 
            text = "".encode() # the chunks are in bytes
            for chunk in r.iter_content(1024):
                text += chunk
        return text.decode()
    except requests.exceptions.Timeout as e:
        print("The server did not respond in time")
        # here it will return None, you can filter it later

DF = pd.DataFrame([fetch_text(link) for link in list_of_links],
                    columns=column_names)

【讨论】:

  • 谢谢 - 很棒的材料。将包括它,看看我能不能解决
  • @arabinelli - 谢谢 - 这看起来棒极了。
  • 很高兴它有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 2018-10-24
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多