首页 > 解决方案 > 从 csv url 列表下载大量 pdf 文件

问题描述

我有一个 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 个文件批量触发下载?而不是一一下载。

标签: pythonseleniumpdfweb-scraping

解决方案


下载文件时,大多数情况下selenium都是矫枉过正的,尽管有时这是唯一有效的方法。

对我来说最好用的是requestswith multiprocessing。为此,请创建一个函数来下载给定 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 并行下载文件”找到更多信息。


推荐阅读