Skip to main content
 首页 » 编程设计

python之使用多线程改进 Python 抓取代码

2025年02月15日32Renyi-Fan

我正在使用 urllib2、bsoup、csv 编写一个简单的 python 爬虫...(Python 2.7) 我有一个 .csv 文件,其中存储了需要删除的 url 链接。

从下面的代码中,我从链接中抓取特定数字,它从网站中找到最多一个参加者,并且 crawl(url) 功能正常工作,就像整个代码一样。

from bs4 import BeautifulSoup 
import json, csv, urllib2, urllib, re, time, lxml 
 
def crawl(url): 
    request = urllib2.Request(url, headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"}) 
    response = urllib2.urlopen(request) 
    readd = response.read() 
 
    soup = BeautifulSoup(readd, "lxml") 
    response.close() 
    maxx = 0 
    if (soup.find("div", attrs={"class" : "attendees-placeholder placeholder"})): 
        exists = soup.find("div", attrs={"class" : "attendees-placeholder placeholder"}) 
        nmb = exists.find("ul", "user-list") 
        numbe = nmb.find_all("li") 
        number = len(numbe) 
        if (number > maxx): 
            maxx = number 
    else: 
        number = 0 
 
    print maxx 
 
 
 
urls = csv.reader(open('all_links_2017.csv')) 
 
 
for url in urls: 
    crawl(url[0]) 

与此同时,速度太慢了,因为我有大约 100000 个网址。 我尝试了很多多线程示例,但这不是我所期望的。 有什么方法可以改进这段代码,让它运行得更快吗? (即多线程、池...)

请您参考如下方法:

你试过了吗?:

import threading 
 
def crawl(url, sem): 
    # Semaphore grabs a thread 
    sem.acquire(blocking=False) 
    # Your code here 
    . 
    . 
    . 
    # All the work is done (i.e. after print maxx) 
    sem.release()  
 
sem = threading.Semaphore(4) 
threads = [threading.Thread(target=crawl, args=(url, sem, )) for url in urls] 
 
for thread in threads: 
    thread.start() 

编辑:首先将 for 更改为列表理解。

编辑:添加了 threading.Semaphore() 限制方法。信号量是一个限制器(本质上是线程计数器),用于跟踪并发运行的线程数。在这种情况下,该值在任何给定时间都设置为最多 4 个线程。如果您选择使用 BoundedSemaphore(),这也可以与 with 上下文管理器一起使用。