爬虫:爬到的数据存到mysql中、爬虫和下载中间件、加代理,cookie、header、加入selenium、集成selenium、==去重规则源码分析(布隆过滤器)、布隆过滤器、scrapy-redis实现分布式爬虫

wxlxl / 2023-06-27 / 原文

目录
  • 爬到的数据存到mysql中
  • 爬虫和下载中间件
  • 加代理,cookie、header、加入selenium
    • 加代理
    • 加cookie、修改请求头、随机生成UserAgent
  • 集成selenium
  • ==去重规则源码分析(布隆过滤器)
  • 布隆过滤器
  • ==scrapy-redis实现分布式爬虫
  • 拓展

爬到的数据存到mysql中


爬虫和下载中间件

# 爬虫中间件:处于爬虫和引擎之间的
# 下载中间件:处于引擎和下载器之间的

# 咱们主要用的是下载中间件,爬虫中间件,了解即可
     进来的时候是个Request对象
     出去的时候是个Response对象
# 爬虫中间件
class FirstscrapySpiderMiddleware:
    # 进入到爬虫时,触发它
    def process_spider_input(self, response, spider):
        return None
    # 出爬虫时,触发它
    def process_spider_output(self, response, result, spider):
        for i in result:
            yield i
    #出异常时,触发它
    def process_spider_exception(self, response, exception, spider):
        pass
    # 第一次爬取,
    def process_start_requests(self, start_requests, spider):
        for r in start_requests:
            yield r

    # 爬虫开启会触发
    def spider_opened(self, spider):
        spider.logger.info("Spider opened: %s" % spider.name)

# 下载中间件

class FirstscrapyDownloaderMiddleware:
   # 请求来了,从引擎进入到下载器会触发,这里有request对象
    def process_request(self, request, spider):
        # 必须返回以下情况:
        # - return None:继续下一个中间件
        # - return a Response object:结束掉,这个请求就不爬取了,回到引擎中
        # - return a Request object :把请求对象给引擎,引擎把它再次放到调度器中,等待下一次调度
        # - raise IgnoreRequest: 就会执行process_exception() 
        return None

    def process_response(self, request, response, spider):
        # 请求下载完成,回来经过:request请求对象, response响应对象
        # - return a Response object:继续走下一个中间件的process_response
        # - return a Request object :把请求对象给引擎,引擎把它再次放到调度器中,等待下一次调度
        # - raise IgnoreRequest:就会执行process_exception() 
        return response

    def process_exception(self, request, exception, spider):
        中间件中抛异常会走到
        pass

 # 下载中间件的process_request,因为有request对象,就是要爬取的对象
     修改请求头
     加cookie
     加代理
    --------
     集成selenium

加代理,cookie、header、加入selenium

加代理

在中间件里写东西 想要生效 先把配置文件的设置打开
DOWNLOADER_MIDDLEWARES = {
   "firstscrapy.middlewares.FirstscrapyDownloaderMiddleware": 543,
}
# 第一步:
    # 在下载中间件写process_request方法
    def get_proxy(self):
        import requests
        res = requests.get('http://127.0.0.1:5010/get/').json()
        if res.get('https'):
            return 'https://' + res.get('proxy')
        else:
            return 'http://' + res.get('proxy')
     def process_request(self, request, spider):
            request.meta['proxy'] = self.get_proxy()
            return None
# 第二步:代理可能不能用,会触发process_exception,在里面写
    def process_exception(self, request, exception, spider):
        print('-----',request.url)  # 这个地址没有爬
        return request

加cookie、修改请求头、随机生成UserAgent

###  加cookie
def process_request(self, request, spider):
        print(request.cookies)
        request.cookies['name']='lqz'
        return None
# 修改请求头
    def process_request(self, request, spider):
        print(request.headers)
        request.headers['referer'] = 'http://www.lagou.com'
        return None
# 动态生成User-agent使用
    def process_request(self, request, spider):
        # fake_useragent模块
        from fake_useragent import UserAgent
        ua = UserAgent()
        request.headers['User-Agent']=str(ua.random)
        print(request.headers)

        return None

集成selenium


==去重规则源码分析(布隆过滤器)


布隆过滤器


==scrapy-redis实现分布式爬虫


拓展

# 原来的去重规则
class RFPDupeFilter(BaseDupeFilter):
   def request_seen(self, request):
        # request_fingerprint 生成指纹
        fp = self.request_fingerprint(request) #request当次要爬取的地址对象
        #判断 fp 在不在集合中,如果在,return True
        if fp in self.fingerprints:
            return True
        #如果不在,加入到集合,return False
        self.fingerprints.add(fp)
        return False


# scrapy-redis的去重规则
class RFPDupeFilter(BaseDupeFilter):
    def request_seen(self, request):
        fp = self.request_fingerprint(request)
        # This returns the number of values added, zero if already exists.
        added = self.server.sadd(self.key, fp)
        return added == 0
    
    
    
    
# 持久化
class RedisPipeline(object):

    def process_item(self, item, spider):
        return deferToThread(self._process_item, item, spider)
    def _process_item(self, item, spider):
        key = self.item_key(item, spider)
        data = self.serialize(item)
        self.server.rpush(key, data)
        return item

# 扩展
https://zhuanlan.zhihu.com/p/91643259
https://www.zhihu.com/column/c_1175438244715651072