scrapy一次启动多个爬虫(cmdline和subprocess两种方式)

scrapy一次启动多个爬虫

有时候我们会写一些比较通用的爬虫,然后通过传递不同参数实现不同网站或者不同页面类型的爬取。
这种情况下,要启动多个爬虫,我们有两种方式:

  • 通过继承cmdline来自定义crawlall来实现
  • 通过多线程的方式依次启动爬虫(可以实现顺序执行)

通过subprocess.Popen实现多个爬虫的启动

subprocess.Popen可以实现

subprocess.Popen顺序启动爬虫

下面的代码中,

  • env添加pythonpath避免导入问题
  • while循环实时log输出
def run_command(command):
    env = os.environ.copy()
    if os.name == 'nt':
        env['PYTHONPATH'] = dirname(dirname(dirname(abspath(__file__)))) + ';' + dirname(dirname(abspath(__file__)))
    else:
        env['PYTHONPATH'] = dirname(dirname(dirname(abspath(__file__)))) + ':' + dirname(dirname(abspath(__file__)))
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, env=env)
    while True:
        output = process.stdout.readline()
        if process.poll() is not None:
            break
        if output:
            print(output.decode('utf-8').strip())

# 依次启动多个爬虫,同时只有一个在运行
for scrapy_cmd in scrapy_cmd_list:
	run_command(scrapy_cmd)

subprocess.Popen并行执行爬虫

def run_command(command):
    env = os.environ.copy()
    if os.name == 'nt':
        env['PYTHONPATH'] = dirname(dirname(dirname(abspath(__file__)))) + ';' + dirname(dirname(abspath(__file__)))
    else:
        env['PYTHONPATH'] = dirname(dirname(dirname(abspath(__file__)))) + ':' + dirname(dirname(abspath(__file__)))
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, env=env)
    return process

process_list = []
# 启动多个爬虫,同时在运行
for scrapy_cmd in scrapy_cmd_list:
	process = run_command(scrapy_cmd)
	process_list.append(process)

while process_list:
    for process in process_list:
        output = process_list.stdout.readline()
        if output:
            print(output.decode('utf-8').strip())
        if process.poll() is not None:
            output = process.stdout.readline()
            if output:
                print(output.decode('utf-8').strip())
            process_list.remove(process)

为什么不直接用scrapy.cmdline.execute或者os.system来直接执行?

因为在scrapy框架中,当一个爬虫执行完毕后,会直接退出程序,而不是继续执行后面代码。

cmdline.execute('scrapy crawl myspider'.split())
print('程序结束')

程序结束不会输出,因为cmdline.execute结束后程序直接退出了。os.system则会在pythonpath上出问题,所以采用可以设置环境变量的subprocess.Popen

通过自定义cmdline实现多个爬虫启动

自定义cmdline可以实现自由的传参,启动多个爬虫,以及为不同爬虫传递不同参数等

class Command(ScrapyCommand):
    requires_project = True

    def syntax(self):
        return '[options]'

    def short_desc(self):
        return 'Runs all of the spiders'

    def add_options(self, parser):
        ScrapyCommand.add_options(self, parser)
        parser.add_option("-a", dest="spargs", action="append", default=[], metavar="NAME=VALUE",
                          help="set spider argument (may be repeated)")

    def process_options(self, args, opts):
        ScrapyCommand.process_options(self, args, opts)
        try:
            opts.spargs = arglist_to_dict(opts.spargs)
        except ValueError:
            raise UsageError("Invalid -a value, use -a NAME=VALUE", print_help=False)

	def run(self, args, opts):
		arg1 = opts.spargs['arg1']
		arg2 = opts.spargs['arg2']
		spider_list = ['sp1', 'sp2']
		for spider_name in spider_list:
        	self.crawler_process.crawl(spider_name, arg1, arg2)
        self.crawler_process.start()

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个基于Scrapy框架开发的微信公众号爬虫程序的示例代码: 首先,我们需要在命令行中安装Scrapy和其他相关依赖: ``` pip install scrapy pip install scrapy-user-agents pip install scrapy-redis pip install scrapy-splash ``` 然后,创建一个新的Scrapy项目: ``` scrapy startproject wechat_spider ``` 接下来,进入项目目录并创建一个Spider: ``` cd wechat_spider scrapy genspider wechat_spider weixin.sogou.com ``` 在Spider中,我们需要定义要爬取的URL和页面元素的解析方法。下面是示例代码: ```python import scrapy from scrapy_splash import SplashRequest from scrapy_redis.spiders import RedisSpider class WechatSpider(RedisSpider): name = 'wechat_spider' allowed_domains = ['weixin.sogou.com'] start_urls = ['https://weixin.sogou.com/'] def parse(self, response): # 构造搜狗微信搜索的URL keyword = 'Python' url = f'https://weixin.sogou.com/weixin?type=1&s_from=input&query={keyword}&ie=utf8&_sug_=n&_sug_type_=' yield SplashRequest(url, self.parse_search_result, args={'wait': 10}) def parse_search_result(self, response): # 解析搜狗微信搜索结果页面 articles = response.css('.news-box .news-list li .txt-box h3 a::attr(href)').getall() for article_url in articles: yield SplashRequest(article_url, self.parse_article, args={'wait': 10}) def parse_article(self, response): # 解析公众号文章页面 title = response.css('#activity-name::text').get() content = response.css('#js_content').get() yield {'title': title, 'content': content} ``` 在这个示例中,我们使用了Scrapy-Redis、Scrapy-Splash和Scrapy-User-Agents等扩展库。我们首先在parse方法中构造搜狗微信搜索的URL,并使用SplashRequest发送请求。在parse_search_result方法中,我们解析搜狗微信搜索结果页面,获取每篇文章的URL,并再次使用SplashRequest发送请求。最后,在parse_article方法中,我们解析公众号文章页面,获取文章标题和内容,并通过yield返回给Scrapy框架。 在运行爬虫之前,我们需要在settings.py中配置Redis和Splash的相关参数: ```python # Redis配置 REDIS_HOST = 'localhost' REDIS_PORT = 6379 REDIS_PARAMS = {'password': 'your_password'} # Splash配置 SPLASH_URL = 'http://localhost:8050' # 下载中间件配置 DOWNLOADER_MIDDLEWARES = { 'scrapy_user_agents.middlewares.RandomUserAgentMiddleware': 400, 'scrapy_splash.SplashCookiesMiddleware': 723, 'scrapy_splash.SplashMiddleware': 725, 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810, } # 爬虫中间件配置 SPIDER_MIDDLEWARES = { 'scrapy_splash.SplashDeduplicateArgsMiddleware': 100, } # Splash参数配置 SPLASH_ARGS = { 'wait': 5, 'images': 0, 'render_all': 1, 'lua_source': """ function main(splash, args) splash.private_mode_enabled = false assert(splash:go(args.url)) assert(splash:wait(args.wait)) return splash:html() end """, } ``` 最后,使用以下命令启动爬虫: ``` scrapy crawl wechat_spider ``` 这是一个简单的微信公众号爬虫程序示例,你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值