全栈爬虫
CrawlSpider全栈爬取的一个类
创建项目后创建爬虫文件:scrapy genspider-t crawl spiderName www.xxx.com
当前文件:D:\python_test\scrapyProject\crawl_spider\crawl_spider\spiders\spider_all.pyimport scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import CrawlSpiderItemclass SpiderAllSpider(CrawlSpider):name = 'spider_all'start_urls = ['https://sc.chinaz.com/jianli/free.html']# allow带正则表达,表示提取当前响应数据满足该正则的urllink = LinkExtractor(allow=r'/jianli/free_\d+\.html')# link_detail = LinkExtractor(allow=r'/jianli/free_\d+\.html')rules = (# Rule对匹配到的link数据发起请求,然后使用callback调用函数进行解析# follow=True表示把每一个请求当做首页来处理,一般在页码可以使用到,不需要则不填该参数# 可填写多个规则进行匹配,但两个Rule是无法直接使用item进行关联的,因此如果想有item关联,还是使用原来的方法Rule(link, callback='parse_item', follow=False),# Rule(link_detail, callback='detail_item'),)def parse_item(self, response):div_list = response.xpath('//*[@id="container"]/div')for div in div_list:title = div.xpath('./p/a/text()').extract_first()detail_url = "https:"+div.xpath('./p/a/@href').extract_first()item=CrawlSpiderItem()item['title']=titleyield scrapy.Request(url=detail_url,callback=self.detail_parse,meta={'item':item})return itemdef detail_parse(self,response):item = response.meta['item']downloadurl=response.xpath('//*[@id="down"]/div[2]/ul/li[2]/a/@href').extract_first()item['url']=downloadurlreturn item
分布式爬虫
创建基于crawlSpider的爬虫文件
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider
from ..items import FbsproItem
class FbsSpider(RedisCrawlSpider): # 导入父类name = 'fenbushi'redis_key = 'queue' # redis_key表示调度器队列的名称,用来替换start_url,以下就是常规解析操作rules = (#提取所有的页码链接,且对其进行请求发送Rule(LinkExtractor(allow=r'id=1&page=\d+'), callback='parse_item', follow=True),)def parse_item(self, response):li_list = response.xpath('/html/body/div[2]/div[3]/ul[2]/li')for li in li_list:title = li.xpath('./span[3]/a/text()').extract_first()statu = li.xpath('./span[2]/text()').extract_first()item = FbsproItem()item['title'] = titleitem['status'] = statusyield item# 修改setting文件
# 所有电脑都执行同一套代码后,在暂停的时候在redis工具输入命令 lpush queue https://mp.csdn.net/mp_blog/(即起始url)
修改setting文件
1、常规内容修改(robots和ua等)2、指定可以被共享的管道类
ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 400}3、指定可以被共享的调度器
# 使用scrapy-redis组件的去重队列
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 是否允许暂停,当程序中止后重新运行,可以在停止位置继续执行
SCHEDULER_PERSIST = True4、指定数据库
REDIS_HOST = '指定redis的ip'
REDIS_PORT = 6379
连续本地的话,修改redis数据库的配置文件(redis.windows.conf)
bind 127.0.0.1
#将上述代码注释即可(解除本机绑定,实现外部设备访问本机数据库)如果配置文件中还存在:protected-mode = true,将true修改为false,
修改为false后表示redis数据库关闭了保护模式,表示其他设备可以远程访问且修改你数据库中的数据
最后,所有电脑都执行同一套代码后,在暂停的时候在redis工具输入命令 lpush queue https://mp.csdn.net/mp_blog/(即起始url)
增量式爬虫
用来监测网站数据更新的情况,爬取网站最新更新出来的数据。
数据指纹:数据的唯一标识。
import scrapy
import redis
from ..items import Zlsdemo1ProItem
class DuanziSpider(scrapy.Spider):name = 'duanzi'start_urls = ['https://ishuo.cn/']#Redis的链接对象conn = redis.Redis(host='127.0.0.1',port=6379)def parse(self, response):li_list = response.xpath('//*[@id="list"]/ul/li')for li in li_list:content = li.xpath('./div[1]/text()').extract_first()title = li.xpath('./div[2]/a/text()').extract_first()all_data = title+content#生成该数据的数据指纹import hashlib # 导入一个生成数据指纹的模块m = hashlib.md5()m.update(all_data.encode('utf-8'))data_id = m.hexdigest()ex = self.conn.sadd('data_id',data_id)if ex == 1:#sadd执行成功(数据指纹在set集合中不存在)print('有最新数据的更新')item = Zlsdemo1ProItem()item['title'] = titleitem['content'] = contentyield itemelse:#sadd没有执行成功(数据指纹在set集合中存储)print('暂无最新数据更新')
使用详情页的url充当数据指纹import scrapy
import redis
from ..items import Zlsdemo2ProItem
class JianliSpider(scrapy.Spider):name = 'jianli'start_urls = ['https://sc.chinaz.com/jianli/free.html']conn = redis.Redis(host='127.0.0.1',port=6379)def parse(self, response):div_list = response.xpath('//*[@id="container"]/div')for div in div_list:title = div.xpath('./p/a/text()').extract_first()#充当数据指纹detail_url = 'https:'+div.xpath('./p/a/@href').extract_first()ex = self.conn.sadd('data_id',detail_url)item = Zlsdemo2ProItem()item['title'] = titleif ex == 1:print('有最新数据的更新')yield scrapy.Request(url=detail_url,callback=self.parse_detail,meta={'item':item})else:print('暂无数据更新')def parse_detail(self,response):item = response.meta['item']download_url = response.xpath('//*[@id="down"]/div[2]/ul/li[1]/a/@href').extract_first()item['download_url'] = download_urlyield item