首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从网站下载年度报告的脚本(总计70,000份)

从网站下载年度报告的脚本(总计70,000份)
EN

Code Review用户
提问于 2019-09-15 15:47:15
回答 1查看 424关注 0票数 3

它只有38行代码,而且我以前还没有这么多地使用过网络抓取。

  • 我的代码在他们的服务器上会有多重?
  • 这是为了深度学习的目的,我还没有运行它,但一旦我开始下载70k的pdfs,它会导致我的IP被禁止四分之一的方式吗?

而且,我也不知道这样做的效率有多高(现在我甚至不知道文件是否存在,而且每次运行程序时我都会覆盖它,所以如果我的代码中途中断,我就必须再次运行它,它就会从头开始下载所有文件)。我必须解决这个问题)。

但无论如何,这是代码:

代码语言:javascript
复制
# Scrapes all pdfs off from www.annualreports.com
# Haven't tested yet but should be somewhere around 70,963 pdfs since my empty search returned 5,479/5,674 stated companies

import requests
from urllib.parse import urljoin
import pandas as pd
from bs4 import BeautifulSoup as bs
import os, re
import pickle

def extract_table():
    r = requests.get('http://www.annualreports.com/Companies?search=')
    soup = bs(r.content, 'lxml')
    df = pd.DataFrame([(i.text, 'http://www.annualreports.com' + i['href']) for i in soup.select('tbody td:nth-of-type(1) a')], columns = ['Company','Link'])
    df.to_pickle('links.pkl') # saves into a dataframe the name of the company plus the href link it points to

def scrap_pdfs():
    df = pd.read_pickle('links.pkl')
    a = 0 # for naming the filenames numerically

    for x in range(df.Link.count()):

        url = df['Link'][x] # reads the "Link" column from the dataframe

        folder_location = r'/home/duke/Annual_Reports/Data' # SPECIFY FULL DIRECTORY

        response = requests.get(url)
        soup= bs(response.text, "html.parser")

        for link in soup.select("a[href$='.pdf']"): #goes through all the .pdfs in all of the href links

            #filename = os.path.join(folder_location, ['href'].split('/')[-1]) # Names the pdf files using the last portion of each link

            filename = os.path.join(folder_location, str(a))
            a+=1

            with open(filename, 'wb') as f:
                f.write(requests.get(urljoin(url,link['href'])).content)
EN

回答 1

Code Review用户

发布于 2019-09-18 00:12:11

是的,现在这将效率低下,我肯定地说,使用可预测的文件名将是这里的第一个关键更改,如果链接目标或描述不能作为文件名的一部分使用,请考虑对其进行散列。简单地列举所有链接是次优的:如果,即使以前的文件保存在周围而不是覆盖,在运行之间运行网站的内容更改(看起来很有可能,不是吗?)突然间,下载文件的顺序与磁盘上的顺序不匹配?一定要做点什么。

第二,代码将创建那个泡菜文件分开,因为它应该多次运行?有点奇怪,但作为一个临时数据库,为什么不呢?我通常认为泡菜文件是短暂的,因为格式是(曾经?)特定于Python。

然后,只需检查文件是否存在并跳过它(也可能检查它是否为非空文件;在下载完整数据之前,还可以对返回内容大小的HTTP头进行比较,然后再实际下载完整文件)。

数据框架上的range应该更简单,但现在我无法找到更简单的方法(不是使用索引,而是简单地遍历值本身)。

f.write(requests.get(...).content) -我认为这会在内存中缓冲完整的文件。最好不要这样做,相反,requests可能有一些工具可以直接写入文件(或类似文件的对象),或者下载的内容必须逐个读取到一个小缓冲区中,并将其与将该缓冲区写入输出文件交替。

最后,格式可以更一致(大部分表达式之间的空格)。看一看PEP8,或者是一个自动格式化器,就可以自动做到这一点。另外,还应该删除剩余的注释。

对,所以总的来说它是有效的,但是对于生产代码来说,有很多事情可以做,特别是使它成为一个更加充实的脚本(读:解析命令行参数,为输出目录提供默认参数;等等)。解析很好,选择器也很简洁,易于阅读。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/229071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档