十五、学习分布式爬虫之下载器中间件

下载器中间件的介绍
在这里插入图片描述
在这里插入图片描述
方法
在这里插入图片描述
在这里插入图片描述

随机更换请求头

中间件代码
在这里插入图片描述
在这里插入图片描述
爬虫代码
在这里插入图片描述

设置随机代理IP

在这里插入图片描述
代码实现
在这里插入图片描述

无限制爬取猎聘网实例

爬虫liepin.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy.spiders.crawl import CrawlSpider,Rule
from scrapy.linkextractors import LinkExtractor
from ..items import ZhaopinItem

class LiepinSpider(CrawlSpider):
    name = 'liepin'
    allowed_domains = ['liepin.com']
    start_urls = ['https://www.liepin.com/zhaopin/?key=python']

    # https://www.liepin.com/job/1919503055.shtml
    rules = (
        Rule(LinkExtractor(allow=r'https://www.liepin.com/job/\d+\.shtml.*',restrict_xpaths=['//ul[@class="sojob-list"]//a']),callback='parse_job',follow=False),
        Rule(LinkExtractor(allow=r'/zhaopin/.+curPage=\d+',restrict_xpaths=['//div[@class="pagerbar"]//a']),follow=True)
    )

    def parse_job(self, response):
        title = response.css(".title-info h1::text").get()
        company = response.css(".title-info h3 a::text").get()
        city_list = response.css(".basic-infor span::text").getall()
        city = "".join(city_list).strip()
        edu = response.css(".job-qualifications span:nth-child(1)::text").get()
        work = response.css(".job-qualifications span:nth-child(2)::text").get()
        desc_list = response.css(".content-word::text").getall()
        desc = "".join(desc_list).strip()
        item = ZhaopinItem(title=title,company=company,city=city,edu=edu,work=work,desc=desc)
        yield item

items.py
在这里插入图片描述
pipelines.py
在这里插入图片描述
models.py
用来获取代理ip地址、代理过期时间、代理是否被拉黑等信息
在这里插入图片描述
middlewares.py

# -*- coding: utf-8 -*-

# Define here the models for your spider middleware
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html

from scrapy import signals
import requests
from .models import ProxyModel
import threading
import time

class IPDownloaderMiddleware(object):
    def __init__(self):
        super(IPDownloaderMiddleware, self).__init__()
        self.current_proxy = None
        self.update_proxy_url = 'http://d.jghttp.golangapi.com/getip?num=1&type=2&pro=&city=0&yys=0&port=11&time=1&ts=1&ys=0&cs=0&lb=1&sb=0&pb=45&mr=1&regions='
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
        }
        self.update_proxy()
        self.lock = threading.Lock()
        # 创建一个多线程:专门用来管理代理的
        # 管理方式:只要这个代理的时间超过了1分钟,或者是这个代理被拉黑了,那么在多线程中就要更换代理了
        th = threading.Thread(target=self.update_proxy_in_thread)
        th.start()

    def process_request(self, request, spider):
        # 更换代理,是在请求之前更换,也就是在这个函数中更换的
        request.meta['proxy'] = self.current_proxy.proxy_url

    def process_response(self, request, response, spider):
        # 在响应中,通过判断状态码,来判断是否需要更新代理
        if response.status != 200:
            # 标记某个标记位,要更新代理了
            self.lock.acquire()
            self.current_proxy.is_blacked = True
            self.lock.release()
            # 如果这个请求没有被正确的响应到,那么应该重新返回,等待下一次重新请求获取
            return request  #中间件链将停止,并重新调度返回的请求,即重新执行这个类,以便将来下载。
        # 如果是正常的响应,那么一定要记得返回response,否则在爬虫中获取不到
        return response

    def update_proxy(self):
        resp = requests.get(self.update_proxy_url, headers=self.headers)
        proxy_model = ProxyModel(resp.json())
        self.current_proxy = proxy_model
        print("更新了新的代理:%s"%self.current_proxy.proxy_url)


    def update_proxy_in_thread(self):
        # 管理方式:只要这个代理的时间超过了1分钟,或者是这个代理被拉黑了,那么在多线程中就要更换代理了
        count = 0
        while True:
            time.sleep(10)
            if count >= 6 or self.current_proxy.is_blacked:
                self.update_proxy()
                count = 0
            else:
                count += 1
                print("count+1=%d"%count)


分布式爬虫

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
爬取步骤:Spiders -> Scheduler -> redis(调度和去重)-> Schedule -> Downloader -> Spider -> pipelines -> redis(下载数据)
Redis介绍
redis是一种支持分布式的nosql数据库,他的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,有丰富的的数据结构(string,list列表[队列和栈],set[集合],sorted set[有序集合],hash(hash表))
nosql数据库:非关系型数据库
redis配置

  1. 再Ubuntu上安装redis:sudo apt install redis-server
  2. 连接redis服务器:redis-cli -h [ip地址] -p [端口号]
  3. 在其他电脑上连接本机的redis服务器:在/etc/redis/redis.conf中,修改bind,把redis服务器的ip地址加进去

爬虫部署

  1. 在服务器(linux)上安装scrapyd:pip3 install scrapyd
  2. 从/usr/local/lib/python3.6/dist-packages/scrapyd下拷贝出default_scrapyd.conf放到/etc/scrapyd/scrapyd.conf。如果没有这个配置文件,自己创建一个即可。
  3. 修改/etc/scrapyd/scrapyd.conf中的bind_address为自己的ip地址
  4. 在开发机上(自己的Windows电脑上)安装pip install scrapyd-client
  5. 修改python/Script/scrapyd-deploy为scrapyd-deploy.py
  6. 在项目中,找到scrapy.cfg,然后配置如下
    `
    [settings]
    default = lianjia.settings

[deploy]
url = http://服务器的IP地址:6800/
project = lianjia`

  1. 在项目所在的路径执行命令:D:\python38\Scripts\scrapyd-deploy.py,生成版本号
  2. 在cmd中使用命令发布爬虫:curl http://服务器的IP地址:6800/schedule.json -d project=项目名称 -d spider=爬虫名称
    如果修改了代码,那么需要重新部署,重新发布爬虫

运行分布式爬虫

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值