爬虫--CrawlSpider及深度全站爬取
CrawlSpider:
--是Spider的一个子类.Spider是爬虫文件中爬虫类的父类
--作用:被用于专业实现全站数据爬取,将一个页面上所有页码对应的数据进行爬取
--基本使用:
--创建一个基于CrawlSpider的爬虫文件
--scrapy genspider -t crawl SpiderName www.xxx.com
--注意:
1.一个链接提取器对应一个规则解析器
2.在实现深度爬取的过程中需要和scrapy.Request()结合使用
基本代码:
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class BlueSpider(CrawlSpider): name = 'blue' # allowed_domains = ['www.xxx.com'] # 域名限定,只允许该域名下的链接 start_urls = ['https://www.xxx.com/category/xxx/page/1'] # 实例化LinkExtractor对象 # 链接提取器:指定规则(allow参数)在页面中提取url # allow='正则':提取链接的规则 link = LinkExtractor(allow=r'category/xxx/page/\d+') rules = ( # 实例化一个Rule对象 # 规则解析器:接收链接提取器提取到的链接,发起请求,然后根据指定规则(callback)解析数据 # 一个链接提取器对应一个规则解析器 # follow=True:可以将链接提取器继续作用到链接提取器提取到的链接所对应的页面中 Rule(link, callback='parse_item', follow=True), ) def parse_item(self, response): # 基于response实现数据解析 print(response)
多规则(Rule)全站深度数据爬取示例:
# 爬虫文件blue.py
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from bluespider.items import BluespiderItem,DetailItem class BlueSpider(CrawlSpider): name = 'blue' # allowed_domains = ['www.xxx.com'] # 域名限定,只允许该域名下的链接 start_urls = ['https://www.fuzokuu.com/category/xxx/page/1'] # 实例化LinkExtractor对象 # 链接提取器:指定规则(allow参数)在页面中提取url # allow='正则':提取链接的规则 # link = LinkExtractor(allow=r'category/xxx/page/d+|category/xxx') link = LinkExtractor(allow=r'category/xxx/page/2') link_detail = LinkExtractor(allow=r'https://www.xxx.com/\d+') rules = ( # 实例化一个Rule对象 # 规则解析器:接收链接提取器提取到的链接,发起请求,然后根据指定规则(callback)解析数据 # 一个链接提取器对应一个规则解析器 Rule(link, callback='parse_item', follow=True), Rule(link_detail, callback='parse_detail', follow=False) ) # 只有手动传参scrapy.Request能够自动传参item # 此处两个函数无法传参item,因此就建立两个item def parse_item(self, response): # 基于response实现数据解析 # 注意:xpath表达式中不可以出现tbody iframe等标签 article_list = response.xpath('//article') for article in article_list: article_title = article.xpath('./div[2]/header/h2/a/@title').extract_first() article_url = article.xpath('./div[2]/header/h2/a/@href').extract_first() article_author = article.xpath('./div[2]/div[2]/span[1]/span/a/@title').extract_first() # 因为有两个item分别存储数据,因此用article_id作为两个item数据之间联系的唯一标识 article_id = article_url.split('/')[-1] item = BluespiderItem() item['article_title'] = article_title item['article_url'] = article_url item['article_author'] = article_author item['article_id'] = article_id yield item # print(article_title, article_url, article_author) # 内容详情页解析 def parse_detail(self, response): content = response.xpath('//article//p/text()').extract() article_id = response.xpath('//article/@id').extract_first() content = ''.join(content) article_id = article_id.split('-')[-1] item = DetailItem() item['content'] = content item['article_id'] = article_id yield item # print(content)
# items.py
import scrapy class BluespiderItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() article_title = scrapy.Field() article_url = scrapy.Field() article_author = scrapy.Field() # article_id作为两个item的共同标识,方便数据库存储 article_id = scrapy.Field() class DetailItem(scrapy.Item): article_id = scrapy.Field() content = scrapy.Field()
# pipelines.py
from itemadapter import ItemAdapter class BluespiderPipeline: def process_item(self, item, spider): # 如何判断item的类型 if item.__class__.__name__ == 'DetailItem': print(item['article_id'],item['content']) else: print(item['article_id'],item['article_title']) return item
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通