【问题标题】:Download large amount of pdf files from csv url list从 csv url 列表下载大量 pdf 文件
【发布时间】:2020-12-12 13:46:10
【问题描述】:

我有一个 csv 文件,其中包含 95k 个 url 链接,这些链接都是 pdf 文件。 我使用 selenium 首先登录页面,然后循环文件以触发下载到我的文件中。

这是我的简单代码

download_dir=r"C:\Users\Me\Downloads\pdfs"
    
chrome_options = Options()
chrome_options.add_experimental_option('prefs',  {
    "download.default_directory": download_dir,
    "download.prompt_for_download": False,
    "download.directory_upgrade": True,
    "plugins.always_open_pdf_externally": True
    }
)

driver = webdriver.Chrome(executable_path=r"C:\Users\Me\Downloads\chromedriver_win32\chromedriver.exe",options = chrome_options)                     
driver.get('https://url.com/')

username = driver.find_element_by_id("email")
password = driver.find_element_by_id("password")

username.send_keys("email@domain.com")
password.send_keys("password")
driver.find_element_by_name("Login_Button").click()

driver.find_element_by_name("company").click()
driver.find_element_by_name("Continue_Button").click()

with open(r'C:\Users\Me\Documents\csvTest.csv', newline='', encoding='utf-8-sig') as csvfile:
    csv_reader = csv.reader(csvfile)
    
    for row in csv_reader:
        pdfUrl = row[0]
        driver.get(pdfUrl)

目前它正在一个一个地执行大约每小时 1500 个文件。我阅读了有关多处理的信息,但我不熟悉如何实现它,而且鉴于正在启动的单个驱动程序,我不确定是否可以在这里进行。有没有办法通过 n 个文件批量触发下载?而不是一一下载。

【问题讨论】:

    标签: python selenium pdf web-scraping


    【解决方案1】:

    大多数时候selenium 是下载文件时的过度杀伤力,尽管有时它是唯一有效的方法。

    对我来说最好使用的是requestsmultiprocessing。为此,请创建一个函数来下载给定 url 的文件(如果需要,还可以下载目标文件):

    import requests
    import time
    
    def downloader(url):
    
        filename = url.split('/')[-1]
    
        if not os.path.exists(filename):
            print('File already exists')
            return
    
        for _ in range(5):
            try:
                r = requests.get(url, stream=True)
                break
           except:
               time.sleep(5)
        else:
            print ('Could not fetch file')
            return
    
        if r.status_code == 200:
                with open(filename, 'wb') as f:
                    for chunk in r:
                        f.write(chunk)
    
        return filename
    

    然后创建线程并使用 url 列表映射该函数:

    from multiprocessing.pool import ThreadPool
    n = 10 #Number of threads
    
    results = ThreadPool(n).imap_unordered(downloader, urls)
    for file in results:
        print(file)
    

    我相信这个过程可以大大加快速度。您可以通过谷歌搜索“python 并行下载文件”找到更多信息。

    【讨论】:

    • 感谢您的回复!在你的函数中,我不太确定你的 for 循环是做什么的......
    • 其实用处不大。它只显示已下载的文件。您实际上并不需要它,但如果您删除脚本,将继续执行代码的下一步,而无需等待下载完成。我想你需要等待我想你必须在最后放一个join()
    • 哦,现在我明白了。函数中的 for 循环可确保在互联网连接中断或服务器响应较晚的情况下,您不会收到错误消息,但您会重试下载文件。这种情况最多发生五次。如果所有时间都失败了,您会收到一条消息并继续下一个 url。换句话说,它确保程序不会因为一些没有下载的文件而停止
    【解决方案2】:

    您可能想看看线程,但您必须在多个函数上转换脚本(https://docs.python.org/3/library/threading.htmlhttps://realpython.com/intro-to-python-threading/

    关于实现它,我认为您可以启动一个线程,仅用于在不同选项卡中打开 url 和其他线程以下载信息,关闭选项卡并转到下一个。 这样,我认为脚本可以更快地执行,您还可以使用以下方法禁用 chrome GUI 以增加一些额外的性能:

    options.add_argument('--headless')
    options.add_argument("--disable-gpu")
    

    【讨论】:

    • 目前,当我触发 driver.get(pdfUrl) 时,它会自动下载它如果我尝试打开多个选项卡并在加载时关闭它们多处理我的意思是线程我猜,谢谢你的链接,我马上进入它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 2023-01-04
    • 2014-10-13
    • 2018-04-27
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多