Scrapy:在另一个线程中下载base64图像

时间:2017-05-22 10:12:53

标签: python multithreading scrapy multiprocessing

我有一个像下面这样的Spider,它从API获取信息,除此之外,我想以base64格式下载产品图像,但爬行过程变得如此缓慢,我怎么能用另一种方式来做,例如,使用线程?

location /atri/ {
alias  /var/www/html/atri/;
try_files $uri $uri/ /atri/index.php;

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_index   index.php;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    include /etc/nginx/fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME $request_filename;
}

2 个答案:

答案 0 :(得分:1)

将自己的线程与scrapy混合通常是一个坏主意。此外没有必要,Scrapy正在使用Twisted的Reactor模式实现并发性,并且如果硬件足够大,可以同时处理1000个请求......并且settings.py中的设置允许它。

由于我无法看到您的图片管道建设,也没有看到您的settings.py,这有点猜测,但您应该尝试这两件事:

  1. 增加CONCURRENT_REQUESTS_PER_DOMAIN和CONCURRENT_REQUESTS设置,否则你的蜘蛛会同时只下载有限数量的页面和文件

  2. 检查映像管道是否有任何cpu密集型处理或阻塞行为。

答案 1 :(得分:0)

以下几种方式,一个队列和一堆工作线程进行请求/响应处理和图像下载。

from threading import Thread
from Queue import Queue


class ExampleMobilePhoneSpider(Spider):

    def __init__(self, num_workers=10, q_size=100):
        self.in_q = Queue(q_size)
        self.worker_threads = [Thread(
                                  target=self.worker, args=(self.in_q,))
                              for _ in range(num_workers)]
        for _thread in self.worker_threads:
            _thread.daemon = True
            _thread.start()

    def worker(self):
        while True:
            _url = self.in_q.get()
            Request(_url, callback=self.parse_item)

    def parse(self, response):
        base_url_mobile = 'https://search.example.com/api/search/?category=c11&pageno='
        urls = [base_url_mobile + str(n) for n in range(2)]
        for url in urls:
            self.in_q.add(urljoin(response.url, url))