全站数据爬取的方法
- 基于spider:手动请求
- 基于CrawlSpider
CrawlSpider的使用:
创建一个工程
cd xxx
创建爬虫文件(Crawlspider):
- 指令 scrapy genspider -t crawl xxx www.xxx.com
链接提取器 LinkExtractor
- 作用:根据指定规则(allow="正则")进行指定链接的提取
规则解析器Rule
- 作用:将链接提取器提取到的链接进行指定规则(callback)的解析操作
参数follow = True
- 作用:可以将链接提取器 继续作用到 链接提取器提取到的链接 所对应的页面中
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class SunSpider(CrawlSpider): name = 'sun' # allowed_domains = ['www.xxx.com'] start_urls = ['http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1'] # 链接提取器:根据指定的规则(allow="正则")进行指定链接的提取 link = LinkExtractor(allow=r'id=1&page=d+') rules = ( # Rule规则解析器: Rule(link, callback='parse_item', follow=False), ) def parse_item(self, response): print(response)
需求:爬取sun网站中的编号、新闻标题,新闻内容、编号
分析:爬取的数据不在同一页面中
1、可以使用链接提取器提取所有页码的链接
2、让链接提取器提取所有的新闻详情页的链接
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from sunPro.items import SunproItem,DetailItem # 需求:爬取sun网站中的编号、新闻标题,新闻内容、编号 class SunSpider(CrawlSpider): name = 'sun' # allowed_domains = ['www.xxx.com'] start_urls = ['http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1'] # 链接提取器:根据指定的规则(allow="正则")进行指定链接的提取 link = LinkExtractor(allow=r'id=1&page=d+') link_detail = LinkExtractor(allow=r'id=d+') # http://wz.sun0769.com/political/politics/index?id=458640 # http://wz.sun0769.com/political/politics/index?id=458637 rules = ( # Rule规则解析器: Rule(link, callback='parse_item', follow=True), # follow=True:可以将链接提取器 继续作用到 链接提取器提取到的链接 所对应的页面中 Rule(link_detail,callback='parse_detail') ) # 如下两个解析方法中是不可以实现请求传参的 # 无法将两个解析方法解析的数据存储到同一个item中,因此可以存储到两个item # 解析新闻标题和编号 def parse_item(self, response): # 注意:xpath表达式中不可以出现tbody标签 li_list = response.xpath('/html/body/div[2]/div[3]/ul[2]/li') for li in li_list: new_num = li.xpath('./span[1]/text()').extract_first() new_title = li.xpath('./span[3]/a/text()').extract_first() # print('编号',new_num,'标题',new_title) item = SunproItem() item['title'] = new_title item['new_num'] = new_num yield item # 解析新闻内容和新闻编号 def parse_detail(self,response): new_id = response.xpath('/html/body/div[3]/div[2]/div[2]/div[1]/span[4]/text()').extract_first() new_content = response.xpath('/html/body/div[3]/div[2]/div[2]/div[2]/pre/text()').extract_first() new_content = ''.join(new_content) # print('详情id',new_id,'详情内容',new_content) item = DetailItem() item['new_id'] = new_id item['content'] = new_content yield item