多线程Web刮刀将值存储到Pandas Dataframe

uid 发布于 2019-05-15 multithreading 最后更新 2019-05-15 22:59 20 浏览

我已经构建了一个webscraper(使用Python 3.4)从网页中提取数据并将其存储为Pandas数据框(保存在Excel文件中之前)。这是成功的。但是,我想要增加页数(> 100k),这意味着我现在使用的单线程方法需要很长的时间才能完成。 我需要刮的URL是事先知道的;下面是我当前代码实现的一个选择:

For a in UrlRefs: # This is the masterlist of URLs to scrape (there are around 5000)
         for i in SecondRefs.index # For each of the main pages, there are 29 subpages. The subpage references are contained in a Pandas dataframe 'SecondRefs' along with a description of the webpage.
#the OpenPages function actually performs the webscraping (using BeautifulSoup to parse the pages)
             TempDF = OpenPages(a, SecondRefs.iloc[i,0],SecondRefs.iloc[i,1])
             MainDF=pd.concat([MainDF,Players],ignore_index=True)
我以前没有在Python中使用多线程的经验,但我最初的猜测是29个子页面可能是多线程的 - 我曾试图按如下方式执行此操作:
#code modified from http://www.quantstart.com/articles/Parallelising-Python-with-Threading-and-Multiprocessing
jobs=[]
        for i in range(1, 29):
            thread = threading.Thread(target=OpenPages(a,SecondRefs.iloc[i,0],SecondRefs.iloc[i,1]))
            jobs.append(thread)
            print("thread ",i)
        # Start the threads  
        for j in jobs:
            j.start()
#Ensure all of the threads have finished
        for j in jobs:
            j.join()
MainDF=pd.concat([MainDF,jobs],ignore_index=True)
上述方法在运行时会产生错误,并且似乎并未加快处理速度(创建线程需要大约20秒,此时出现错误;忽略错误,这不会比单个进程快) 我的问题如下: 1)如何在代码中最好地实现多线程来加速处理? 2)我怎样才能将来自每个线程的返回值合并回主熊猫数据框? 预先感谢您的任何帮助。 编辑: 感谢您的答复。 为了记录,我已经为我的问题达成了以下解决方案(尽管如果您愿意,请随时发表评论/评论)。
from multiprocessing.pool import ThreadPool
from random import randrange
 pool = ThreadPool(processes=29)
        thread=[]
        for i in range(1, 29):
            thread.append(pool.apply_async(OpenPages, (a,SecondRefs.iloc[i,0],SecondRefs[i,1])))
            time.sleep(randrange(25,35)/100)
# Start the threads    
        for i in range(1, 29):
            MainDF=pd.concat([MainDF,thread[i].get()],ignore_index=True)
pool.close()
已邀请:

et_ea

赞同来自:

thread = threading.Thread(target=OpenPages(a,SecondRefs.iloc[i,0],SecondRefs.iloc[i,1]))
应该
thread = threading.Thread(target=OpenPages, args=(a,SecondRefs.iloc[i,0],SecondRefs.iloc[i,1]))