【问题标题】:Selenium Multiprocessing Help in Python 3.4Python 3.4 中的 Selenium 多处理帮助
【发布时间】:2017-08-28 15:32:37
【问题描述】:

我在试图使用 Selenium 来获取网站上特定搜索的结果数量时不知所措。基本上,我想让这个过程运行得更快。我的代码通过迭代搜索词然后通过报纸将收集的数据输出到 CSV 来工作。目前,这会在 3 年内生成 3 个搜索词 x 3 份报纸,在每个 CSV 大约 10 分钟内给我 9 个 CSV。

我想使用多处理来同时运行每个搜索和报纸组合,或者至少更快地运行。我尝试在此处遵循其他示例,但未能成功实现它们。以下是我目前的代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import os
import pandas as pd
from multiprocessing import Pool

def websitesearch(search):
    try:
        start = list_of_inputs[0]
        end = list_of_inputs[1]
        newsabbv=list_of_inputs[2]
        directory=list_of_inputs[3]
        os.chdir(directory)

        if search == broad:
            specification = "broad"
            relPapers = newsabbv

        elif search == narrow:
            specification = "narrow"
            relPapers = newsabbv

        elif search == general:
            specification = "allarticles"
            relPapers = newsabbv

        else:
            for newspapers in relPapers:

               ...rest of code here that gets the data and puts it in a list named all_Data...

                browser.close()
                df = pd.DataFrame(all_Data)
                df.to_csv(filename, index=False)          

    except:
        print('error with item')



if __name__ == '__main__':
 ...Initializing values and things like that go here. This helps with the setup for search...

    #These are things that go into the function        
    start = ["January",2015]
    end = ["August",2017]
    directory = "STUFF GOES HERE"
    newsabbv = all_news_abbv
    search_list = [narrow, broad, general]

    list_of_inputs = [start,end,newsabbv,directory]    

    pool = Pool(processes=4)
    for search in search_list:
        pool.map(websitesearch, search_list)
        print(list_of_inputs)        

如果我在 main() 函数中添加一个打印语句,它会打印,但实际上什么都没有发生。我将不胜感激。我省略了获取值并将其放入列表的代码,因为它很复杂,但我知道它有效。

提前感谢您的任何帮助!如果我可以提供更多信息,请告诉我。

艾萨克

编辑:我查看了更多在线帮助并意识到我误解了使用 pool.map(fn, list) 将列表映射到函数的目的。我已经更新了我的代码以反映我目前仍然无法正常工作的方法。我还将初始化值移到了主函数中。

【问题讨论】:

  • 您意识到您的行为违反了他们的服务条款吗? proquest.com/about/terms-and-conditions.html。见 9.e。和 9.i。你可以联系他们,看看他们是否有 API 等,如果它不破坏他们的服务条款,那么可以让你更快地获得你想要的东西。
  • 嗨,杰夫,我已经检查了有关该项目的权力,显然这不是问题。我还编辑了代码以使其更通用,因为我计划将其应用到其他地方。
  • 首先,不工作并没有真正的帮助。解释出了什么问题。还发布完整的最小代码,如果可能的话,可以运行看看

标签: python selenium multiprocessing python-multiprocessing multiprocess


【解决方案1】:

我认为它不能以您的方式进行多处理。因为它仍然有由硒引起的队列进程(不是队列模块)。

原因是...selenium 只能处理一个窗口,不能同时处理多个窗口或标签浏览器(window_handle 功能的限制)。这意味着....您的多进程仅处理内存中发送到硒或由硒爬行的数据进程。通过在一个脚本文件中尝试处理selenium的爬取,将selenium作为瓶颈进程的来源。

制作真正的多进程的最佳方法是:

  1. 制作一个脚本,使用 selenium 处理该 url 以通过 selenium 抓取并将其保存为文件。例如 crawler.py 并确保脚本有打印命令来打印结果

例如:

import -> all modules that you need to run selenium
import sys

url = sys.argv[1] #you will catch the url 

driver = ......#open browser

driver.get(url)
#just continue the script base on your method

print(--the result that you want--)
sys.exit(0)

我可以给出更多解释,因为这是该过程的主要核心,并且您想在该网络上做什么,只有您自己理解。

  1. 制作另一个脚本文件:

一个。分配 url,多进程意味着创建一些进程并与所有 cpu 内核一起运行,这是实现它的最佳方式......它首先是分配输入进程,在你的情况下可能是 url 目标(你不给我们,您要抓取的网站目标)。但是网站的每个页面都有不同的 url。只需收集所有 url 并将其分配给几个组(最佳实践:您的 cpu 核心 - 1)

例如:

import multiprocessing as mp

cpucore=int(mp.cpu_count())-1.

b.使用您之前制作的 crawl.py 将 url 发送到处理(通过子进程或其他模块,例如:os.system)。确保你运行 crawl.py max == cpucore。

例如:

crawler = r'YOUR FILE DIRECTORY\crawler.py'

def devideurl():
    global url1, url2, url3, url4
    make script that result:
    urls1 = groups or list of url
    urls2 = groups or list of url
    urls3 = groups or list of url
    urls4 = groups or list of url

def target1():
    for url in url1:
        t1 = subprocess.Popen(['python', crawler, url], stdout = PIPE)
        #continue the script, base on your need...
        #do you see the combination between python crawler and url?
        #the cmd command will be: python crawler.py "value", the "value" is captured by sys.argv[1] command in crawler.py

def target2():
    for url in url2:
        t1 = subprocess.Popen(['python', crawler, url], stdout = PIPE)
        #continue the script, base on your need...
def target3():
    for url in url1:
        t1 = subprocess.Popen(['python', crawler, url], stdout = PIPE)
        #continue the script, base on your need...
def target4():
    for url in url2:
        t1 = subprocess.Popen(['python', crawler, url], stdout = PIPE)
        #continue the script, base on your need...

cpucore = int(mp.cpu_count())-1
pool = Pool(processes="max is the value of cpucore")
for search in search_list:
    pool.map(target1, devideurl)
    pool.map(target2, devideurl)
    pool.map(target3, devideurl)
    pool.map(target4, devideurl)
    #you can make it, more, depend on your cpu core

c。将打印结果存入主脚本内存

d。继续你的脚本进程来处理你已经得到的数据。

  1. 最后,在主脚本中为整个进程制作多进程脚本。

用这个方法:

你可以同时打开多个浏览器窗口进行处理,而且由于从网站爬取的数据处理速度比内存中的数据处理速度要慢,这种方法至少减少了数据流的瓶颈。意味着它比你以前的方法更快。

希望有帮助...干杯

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2014-03-19
    • 2020-09-21
    • 1970-01-01
    相关资源
    最近更新 更多