DAY 91 爬虫05

1 切换frame,动作链
2 xpath选择:在xml中查找内容的一门语言
-.
   -..
   -/
   -//
   -@
3 自动登录12306
-打码平台使用:别人帮我们破解验证码
   -使用selenium点击,滑动
   -有的网站会校验是否使用了自动化测试软件:
  -window.navigator.webdriver
   -获取验证码
  -验证码图片的位置和大小
  -屏幕截图,pillow抠图
       -base64编码,存成图片,前面有标志部分
       -base64的解码和编码  
       
4 scrapy
-pip3 install scrapy
-7个组件
  -爬虫:spiders文件夹下的一个个py文件,爬取的地址,解析数据
       -爬虫中间件:介于爬虫和引擎之间的
       -引擎:大总管,负责数据的流动
       -调度器:爬取地址的调度和去重
       -下载中间件
       -下载器:负责下载
       -管道:存储,数据清洗
       
  -创建项目,创建爬虫
  -scrapy startproject 名字
       -scrapy genspider 爬虫名  爬虫地址
       -scrapy crawl 爬虫名
-目录结构
   -数据解析
  -xpath
      -拿文本:'.//a/text()'
           -拿属性:'.//a/@href'
       -css
      -拿文本:'a.link-title::text'
           -拿属性:'img.image-scale::attr(src)'
           
       -取一条;extract_first()
       -取多条:extract()

1 setting中相关配置

1 是否遵循爬虫协议
ROBOTSTXT_OBEY = False

2 请求客户端类型
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'

3 日志级别(--nolog好在,如果出错,控制台会报错)
LOG_LEVEL='ERROR'

 

2 持久化方案

1 第一种方案,直接存(很少)
-解析函数返回列表套字典
   -执行:scrapy crawl cnblogs -o 文件名(json,pkl,csv结尾)
   
2 第二种:通用方法(pipline)
-1 在items.py中写一个类,继承scrapy.Item
   -2 在类中写属性
  title = scrapy.Field()
   -3 在爬虫中导入类,实例化得到对象,把要保存的数据放到对象中
  item['title'] = title
   -4 修改配置文件,指定pipline,数字表示优先级,越小越大
  ITEM_PIPELINES = {
  'crawl_cnblogs.pipelines.CrawlCnblogsPipeline': 300,
}
   -5 写一个pipline:CrawlCnblogsPipeline
  -open_spider:数据初始化,打开文件,打开数据库链接
       -process_item:真正存储的地方
      -一定不要忘了return item,交给后续的pipline继续使用
       -close_spider:销毁资源,关闭文件,关闭数据库链接

 

3 全站爬取cnblogs文章(scrapy的请求传参)

3.1 request和response对象传递参数

1 在request对象中
Request(url=url, callback=self.parse_detail,meta={'item':item})
2 在response对象中
item=response.meta['item']

3.2 解析出下一页的地址并继续爬取

next='https://www.cnblogs.com'+response.css('.pager a:last-child::attr(href)').extract_first()
print(next)
# yield Request(url=next,callback=self.parse)
yield Request(url=next)

 

4 提高爬取效率

#1 增加并发:
默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。
#2 降低日志级别:
在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = ‘INFO’
# 3 禁止cookie:
如果不是真的需要cookie,则在scrapy爬取数据时可以禁止cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False
# 4 禁止重试:
对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False
# 5 减少下载超时:
如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s

 

5 爬虫中间件和下载中间件

1 爬虫和下载中间件要使用,需要在配置文件中
SPIDER_MIDDLEWARES = {
 'crawl_cnblogs.middlewares.CrawlCnblogsSpiderMiddleware': 5,
}
DOWNLOADER_MIDDLEWARES = {
 'crawl_cnblogs.middlewares.CrawlCnblogsDownloaderMiddleware': 5,
}

 

6 加代理,加cookie,加header,加selenium

0 在下载中间件的process_reqeust方法中
1 加cookie
# request.cookies['name']='lqz'
   # request.cookies= {}
2 修改header
 # request.headers['Auth']='asdfasdfasdfasdf'
     # request.headers['USER-AGENT']='ssss'
3 加代理
 request.meta['proxy']='http://103.130.172.34:8080'
   
   
4 fake_useragent模块,可以随机生成user-aget
   from fake_useragent import UserAgent
       ua = UserAgent()
       print(ua.ie)   #随机打印ie浏览器任意版本
       print(ua.firefox) #随机打印firefox浏览器任意版本
       print(ua.chrome)  #随机打印chrome浏览器任意版本
       print(ua.random)  #随机打印任意厂家的浏览器
       
5 如果process_request返回的是Request对象
-会交给引擎,引擎把请求放到调度中,等待下次被调度
   
   
6 集成selenium
-在爬虫类中类属性
   driver = webdriver.Chrome(executable_path='')
   -在爬虫类中方法:
     def close(spider, reason):
       spider.driver.close()
   -在中间件中的process_reqeust中
   from scrapy.http import HtmlResponse
   spider.driver.get(url=request.url)
      response=HtmlResponse(url=request.url,body=spider.driver.page_source.encode('utf-8'),request=request)
   return response

 

7 去重规则源码分析

1 使用了集合去重
2 默认使用的去重类:
DUPEFILTER_CLASS = 'scrapy.dupefilters.RFPDupeFilter'
3 后期你可以自己写一个类,替换掉内置的去重
-布隆过滤器:极小内存校验是否重复
-https://www.cnblogs.com/xiaoyuanqujing/protected/articles/11969224.html


4 生成指纹,会把下面两种地址生成一样的指纹(本质是把?后面的参数排序,再生成指纹)
www.baidu.com?name=lqz&age=18
www.baidu.com?age=18&name=lqz
#布隆过滤器
# python中使用
#https://www.lfd.uci.edu/~gohlke/pythonlibs/#bitarray
pip3 install bitarray-xx.whl
pip3 install pybloom_live


from pybloom_live import ScalableBloomFilter
bloom = ScalableBloomFilter(initial_capacity=100, error_rate=0.001, mode=ScalableBloomFilter.LARGE_SET_GROWTH)

url = "www.cnblogs.com"

url2 = "www.liuqingzheng.top"

bloom.add(url)

print(url in bloom)

print(url2 in bloom)

 

8 scrapy-redis实现分布式爬虫

1 安装scrapy-redis
2 在原来的基础上,爬虫类继承RedisSpider
class CnblogsSpider(RedisSpider):
name = 'cnblogs_redis'
allowed_domains = ['www.cnblogs.com']
redis_key = 'myspider:start_urls'
3 在setting中配置
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 默认就是本地6379
#REDIS_HOST = 'localhost'
#REDIS_PORT = 6379
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 400
}

4 在多台机器上启动scrapy,向redis中插入起始爬取地址
scrapy crawl cnblogs_redis

redis-cli lpush myspider:start_urls https://www.cnblogs.com/
原文地址:https://www.cnblogs.com/DEJAVU888/p/14894117.html