(1)scrapy爬取豆瓣具体个人主页的内容
第一步:新建项目
cd ..
scrapy startproject doubanPro
cd doubanPro/
第二步:新建爬虫文件
scrapy genspider douban www.douban.com
第三步:爬虫文件里边的内容
# -*- coding: utf-8 -*- import scrapy class DoubanSpider(scrapy.Spider): name = 'douban' # allowed_domains = ['www.douban.com'] start_urls = ['https://accounts.douban.com/j/mobile/login/basic'] #重写start_requests方法 def start_requests(self): data={ 'ck':'', 'name': '17862982790', 'password': 'spc121314', 'remember': 'false', 'ticket':'' } for url in self.start_urls: yield scrapy.FormRequest(url=url,formdata=data,callback=self.parse) #针对个人主页页面数据进行解析操作 def parseBySecondPage(self,response): fp=open('second.html','w',encoding='utf-8') #个人主页 fp.write(response.text) #可以对当前用户的个人主页页面数据进行指定解析操作 def parse(self, response): #登录成功后的页面数据进行存储 fp=open('main.html','w',encoding='utf-8') #写入 fp.write(response.text) #main应该是登录成功之后的页面,但是没有拿到 #获取当前用户的个人主页 url='https://www.douban.com/people/198409299/' yield scrapy.Request(url=url,callback=self.parseBySecondPage)
第四步:settings.py配置UA和robots配置
第五步:执行scrapy crawl douban --nolog
结果:成功爬取到个人主页,但是存在的问题是,登录之后的页面有问题
(2)scrapy实现IP代理替换goubanjia
第一步:新建项目
cd ..
scrapy startproject proxyPro
cd proxyPro/
第二步:新建爬虫文件
scrapy genspider proxyDemo www.baidu.com/s?wd=ip
第三步:
# -*- coding: utf-8 -*- import scrapy class ProxydemoSpider(scrapy.Spider): name = 'proxyDemo' # allowed_domains = ['www.baidu.com/s?wd'] start_urls = ['https://www.baidu.com/s?wd=ip'] def parse(self, response): fp=open('proxy.html','w',encoding='utf-8') fp.write(response.text)
第四步:配置文件中写UA和robots.py
第五步,执行爬虫文件
scrapy crawl proxyDemo --nolog
(3)请求传参:可以参考课程中的另一个案例学习
首先,创建项目
scrapy startproject moivePro
cd moivePro/
scrapy genspider moive https://www.4567tv.tv/frim/index1.html
moive.py爬虫程序
import scrapy from moviePro.items import MovieproItem class MovieSpider(scrapy.Spider): name = 'movie' # allowed_domains = ['https://www.4567tv.tv/frim/index1.html'] start_urls = ['https://www.4567tv.tv/frim/index1.html'] #专门用于解析二级子页面中的数据值 def parseBySecondPage(self,response): director=response.xpath('/html/body/div[1]/div/div/div/div[2]/p[3]/a/text()').extract_first() region = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[1]/a[1]/text()').extract_first() yeartime= response.xpath('/html/body/div[1]/div/div/div/div[2]/p[1]/a[2]/text()').extract_first() #取出request方法的meta参数传递过来的字典(response.meta item=response.meta['item'] item['director']=director item['region']=region item['yeartime']=yeartime #将item提交给管道 yield item def parse(self, response): #名称,类型,导演,语言,片长 div_list=response.xpath('/html/body/div[1]/div/div/div/div[2]/ul/li')#获取所有的li标签 #主演和名字和地址 for div in div_list: name=div.xpath('./div/div/h4/a/text()').extract_first() top_act=div.xpath('./div/div/p/text()').extract_first() #/html/body/div[1]/div/div/div/div[2]/ul/li[2]/div/a url='https://www.4567tv.tv'+div.xpath('./div/a/@href').extract_first() #创建items对象 item=MovieproItem() item['name']=name item['top_act']=top_act #思考,如何将剩下的电影详情数据存储到item对象中.meta可以实现传递 #需要对url发起请求,获取页面数据,进行指定数据解析 #meta参数只可以赋值一个字典(将item对象先封装到字典) yield scrapy.Request(url=url,callback=self.parseBySecondPage,meta={'item':item})
items.py
import scrapy class MovieproItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() name = scrapy.Field() top_act = scrapy.Field() director = scrapy.Field() region = scrapy.Field() yeartime = scrapy.Field()
pipelines.py
class MovieproPipeline(object): def open_spider(self,spider): self.fp=open('movie.txt','w',encoding='utf-8') def process_item(self, item, spider): detail=str(item['name'])+":"+str(item['top_act'])+":"+str(item['director'])+":"+str(item['region'])+":"+str(item['yeartime']) #有些导演没有数据,需要强转成None才可以 self.fp.write(detail+'\n\n\n') return item def close_spider(self, spider): self.fp.close()
settings.py,开启下面四个参数,日志自己添加
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' # Obey robots.txt rules ROBOTSTXT_OBEY = False LOG_LEVEL='ERROR' ITEM_PIPELINES = { 'moviePro.pipelines.MovieproPipeline': 300, }
执行下面的命令,需要先进入爬虫文件
scrapy crawl moive
(4-1)crawlSpider笔者写这个案例参考网上案例,但是目前抽屉已经更新,不再适用
创建项目
scrapy startproject crawlSpiderPro cd crawlSpiderPro/ scrapy genspider -t crawl chouti dig.chouticom
爬虫初步文件修改:
# -*- coding: utf-8 -*- import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider): name = 'chouti' # allowed_domains = ['dig.chouti.com'] start_urls = ['http://dig.chouti.com/'] #实例化了一个链接提取器对象 link=LinkExtractor(allow=r'Items/') rules = ( #实例化一个规则解析器对象 Rule(link, callback='parse_item', follow=True), ) def parse_item(self, response): pass
另一个参考(课上):
# -*- coding: utf-8 -*- import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider): name = 'chouti' # allowed_domains = ['www.ccc.coim'] start_urls = ['https://dig.chouti.com/all/hot/recent/1'] #链接提取器:从起始url对应的页面中提取符合规则的链接。allow=》正则 link= LinkExtractor(allow=r'/all/hot/recent/\d+') #页码数据提取 rules = ( #规则解析器:将链接提取器提取到的链接对应的页面源码进行指定规则的解析 Rule(link, callback='parse_item', follow=True), #follow:True 将连接提取器 继续 作用到 连接提取器提取出来的链接 对应的页面源码中 ) def parse_item(self, response): print(response)
(4-2)crawlSpider续上
升级:
# -*- coding: utf-8 -*- import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider): name = 'chouti' # allowed_domains = ['dig.chouti.com'] start_urls = ['http://dig.chouti.com/'] #实例化了一个链接提取器对象link #链接提取器:用来提取指定的链接(url) #allow参数:赋值一个正则表达式 #链接提取器就可以根据正则表达式在页面中提取指定的链接 #提取到的链接会全部交给规则解析器 link=LinkExtractor(allow=r'/all/hot/recent/\d+') #页码的链接 rules = ( #实例化一个规则解析器对象 #规则解析器接受了链接提取器发送的连接后,就会对这些链接发起请求,获取链接对应的页面内容, #就会根据指定的规则对页面内容中"指定"的数据值进行解析 #callback:制定一个解析规则(方法或函数) Rule(link, callback='parse_item', follow=False), ) def parse_item(self, response): print(response)
运行:
scrapy crawl chouti --nolog
# -*- coding: utf-8 -*- import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider): name = 'chouti' # allowed_domains = ['dig.chouti.com'] start_urls = ['http://dig.chouti.com/'] #实例化了一个链接提取器对象link #链接提取器:用来提取指定的链接(url) #allow参数:赋值一个正则表达式 #链接提取器就可以根据正则表达式在页面中提取指定的链接 #提取到的链接会全部交给规则解析器 link=LinkExtractor(allow=r'/all/hot/recent/\d+') #页码的链接 rules = ( #实例化一个规则解析器对象 #规则解析器接受了链接提取器发送的连接后,就会对这些链接发起请求,获取链接对应的页面内容, #就会根据指定的规则对页面内容中"指定"的数据值进行解析 #callback:制定一个解析规则(方法或函数) #follow:是否将链接提取器继续作用到连接提取器取出的链接锁表示的页面数据中 Rule(link, callback='parse_item', follow=True), #深入提取数据 #大量重复链接,scrapy会去重 ) def parse_item(self, response): print(response) #可以进行xpath数据的解析
运行:
scrapy crawl chouti --nolog
其他方式和前边的一样
(5)分布式爬虫
爬虫文件qiubai.py
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from redisPro.items import RedisproItem from scrapy_redis.spiders import RedisCrawlSpider class QiubaiSpider(RedisCrawlSpider): name = 'qiubai' # allowed_domains = ['https://www.qiushibaike.com/pic/'] # start_urls = ['http://https://www.qiushibaike.com/pic//'] #下面的值就是调度器队列的名称 redis_key = 'qiubaispider' #表示跟start_urls含义是一样的 link=LinkExtractor(allow=r'/pic/page/\d+') rules = ( Rule(link, callback='parse_item', follow=True), ) def parse_item(self, response): div_list=response.xpath('//div[@id="content-left"]/div') for div in div_list: img_url="https:"+div.xpath('./div[@class="thumb"]/a/img/@src').extract_first() item=RedisproItem() item['img_url']=img_url yield item
items.py
import scrapy class RedisproItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() img_url = scrapy.Field()
settings.py配置
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' # Obey robots.txt rules ROBOTSTXT_OBEY = False #管道 ITEM_PIPELINES = { # 'redisPro.pipelines.RedisproPipeline': 300, 'scrapy_redis.pipelines.RedisPipeline': 400, } #调度器 # 使用scrapy-redis组件的去重队列 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 使用scrapy-redis组件自己的调度器,核心部分 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 是否允许暂停 SCHEDULER_PERSIST = True #如果redis服务器不在自己本机,则需要如下配置 # REDIS_HOST = 'redis服务的ip地址' REDIS_HOST = '192.168.2.7' REDIS_PORT = 6379 # REDIS_ENCODING = 'utf-8' # REDIS_PARAMS = {'password':'123456'}