scrapy startproject name
cd proName
scrapy genspider spiderName urlName(限制爬虫的爬取范围)
执行:scrapy crawl spiderName
start_urls = []=====>列表中的元素会被scrapy自动进行发送--几个url,请求
robotstxt_obey = False
USER_AGENT = ‘ ‘
LOG_LEVEL = ‘ERROR‘
LOG_FILE = ‘log.txt‘----一般不用
xpath返回的列表中的列表元素是selector对象,我们需要解析获取的字符串的数据
必须经过一个extract() 操作才可以将该对象汇总存储的字符串的数据获取
.extract()----列表
.extract_first()-----字符串
---问题:xpath返回的列表中的列表元素有多个(selector对象),想要将每个列表元素对应的selector中的字符串取出--------使用 extract()
xpath语法
通过返回的response数据可以直接直接进行Xpath解析。
基于终端指令:
只可以将parse方法的返回值存储到电脑磁盘中
scrapy crwal first -o file.csv-------->将当前返回值存储到file文件中csv\json
基于管道:>pipelines.py
编码流程
数据解析(在爬虫类中)
在item的类中定义相关的属性(爬虫类)
将解析的数据存储封装到item类型的对象中;
将item对象提交给管道 yield
在管道类中process_item方法负责接收item对象,然后对item进行任意形式的格式持久化存储
在settings中设置MySQL的配置信息
# 如下所示
# mysql 配置
MYSQL_DB_NAME = ‘scrapy_db‘
MYSQL_HOST = ‘127.0.0.1‘
MYSQL_USER = ‘root‘
MYSQL_PASSWORD = ‘123456‘
细节补充:
管道文件中的一个管道类表示将数据存储到某一个形式的平台中。
如果管道文件中定义多个管道类,爬虫类提交的item的操作会给到优先级最高的管道类,只有优先级最高的管道类才可以接受到item,剩下的管道类是需要从优先级最高的管道中接受item;
process_item 方法的实现中的return item的操作表示item传递给下一个即将被执行的管道类
yield scrapy.Request(url,callback)-----发送的get请求
1). 向管道提交item的时候:yield item
2). 手动请求发送:yeld scrapy.Request(url,callback)
yield scrapy.FormRequest(url,formdata,callback):formdata是一个字典表示请求参数
- 略(网上都有)
- 作用:实现深度爬取
- 使用场景:使用scrapy爬取的数据没有存在同一张页面的数据
- 传递item:使用meta的技巧----yield scrapy.Request(url,callback,meta)
- 接受item:response.meta
CONCURRENT_REQUESTS = 100
LOG_LEVEL=‘ERROR‘
COOKIES_ENABLE = True
retry_ebable = False
DOWNLOAD_TIMEOUT = 3----请求超过3,丢弃,
--->处于引擎和下载器
NameDownloaderMiddleware;NameSpiderMiddleware
---必须经过引擎:
首先由调度器(scheduler)到下载器(downloader)之间可以进行request的修改与设置;
再由下载器(downloader)到主爬虫(spider)之间可以进行response的修改与设置;
-- 批量拦截所有的请求响应
-- 拦截请求
-- 篡改请求的头信息(UA伪装)
-- 篡改请求对应的ip(代理)
-- 拦截响应:
-- 篡改响应数据,篡改响应对象
位置:处于scrapy的Request和Response之间的处理模块;
process_request---拦截正常请求,并修改与设置
进行ua伪装:resquest.headers["User-Agent"] = "xxx "
进行代理设置:resquest.meta["proxy"] = proxy
process_response--拦截所有的响应
在downloader执行Request下载后,会得到对应的response,在发送到spider之前,可以使用process_response来对数据进行处理。
process_exception--拦截发生异常的请求对象
当downloader或者process_request()方法抛出异常是,该方法会被调用;
spider Middleware是接入到scrapy的Spider处理机制的钩子框架;
在Downloader生成Response之后,Response会被发送到Spider之前,首先经过SpiderMiddleware处理,当spider处理生成item和Request之后,还会经过SpiderMiddleware处理。
暂时没有用到,只大体学习记录;
- 基于scrapy进行全站数据爬取的一种新的手段
CrawlSpider就是spider的一个子类
链接提取器(LinkExtractor):
规则解析器(Rule):
使用流程
新建一个工程
cd 工程中
新建一个爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com
样例:
1 #demo 2 # -*- coding: utf-8 -*- 3 import scrapy 4 from scrapy.linkextractors import LinkExtractor 5 from scrapy.spiders import CrawlSpider, Rule 6 ? 7 ? 8 class CrawlproSpider(CrawlSpider): 9 name = ‘Crawlpro‘ 10 allowed_domains = [‘www.xxx.com‘] 11 start_urls = [‘http://www.xxx.com/‘] 12 ? 13 rules = ( 14 Rule(LinkExtractor(allow=r‘Items/‘), callback=‘parse_item‘, follow=True), 15 ) 16 ? 17 def parse_item(self, response): 18 item = {} 19 #item[‘domain_id‘] = response.xpath(‘//input[@id="sid"]/@value‘).get() 20 #item[‘name‘] = response.xpath(‘//div[@id="name"]‘).get() 21 #item[‘description‘] = response.xpath(‘//div[@id="description"]‘).get() 22 return item 23 ?
列表有lpush、lpop、rpush、rpop方法,实现先进先出爬取队列,也可以实现先进后出栈式爬取队列
集合元素无需并且不重复
可实现带优先级的调度队列
使用md5生成的数据指纹来筛选数据,将转换的md5值与之前的传入redis中的数据进行比对;
使用哈希算法生成数据指纹筛选数据,将转换的md5值与之前的传入redis中的数据进行比对;
布隆过滤器
编辑距离算法
simhash算法
为什么要防止中断:
在scrapy中,爬虫运行时的Request队列放在内存中,在爬虫运行中中断后,这个空间就被释放,此队列就被销毁,所以一旦爬虫被中断,爬虫再次运行就相当于全新的爬取过程。
解决方法:
将队列中的Request保存起来,再次爬取直接读取保存的数据即可
实现命令:
scrapy crawl spider -s JOB_DIP=crawls/spider(路径使用JOB_DIP标识)
概念:用于检测网站数据更新的情况。
应用的网站类型:
增量式深度爬取
增量式非深度爬取
核心机制:去重;redis-set去重方式(可做持久化存储),python中的set是基于缓存中的
增量式流程:
与基本的爬虫Scrapy流程相似,只是再spider中加了数据指纹的认证
再pipelines中增加了redis的存储过程
rules配置规则
数据库的连接
item数据类型创建完成
pipelines
数据库的调用:spider.方法
redis的存储
框架中的item传输问题(parse传到其他函数中):
传输:
1 yield scrapy.Resquest(url,callback=self.parse_detail,meta={‘item‘:item})
下个函数接收:
1 item = response.meta[‘item‘] 2 item[""] = ... 3 yield item
首先创建好scrapy
文件,注释掉allowed_domains以及start_urls
;重写初始化请求(start_requests)
,最后yield
返回给解析函数。
1 class xxx(scrapy.Spider): 2 name = ‘xxxx‘ 3 #allowed_domains = [‘‘] 4 #start_url = [‘‘] 5 6 def start_requests(self): 7 headers = {} 8 base_url = ‘‘ 9 formdata = {} 10 yield scrapy.FormRequest(url=base_url,headers=headers,formdata=formdata,callback=self.parse) 11 #如果使用FormRequest报错,备选方案 12 scrapy.Request(url=base_url,headers=headers,body=json.dumps(formdata),method= ‘POST‘,callback=self.parse) 13 14 15 def parse(self,response): 16 pass
robots
UA伪装
验证码
代理
cookie
动态变化的请求参数
JS加密
JS混淆
图片懒加载
动态数据的获取
selenium:规避检测
网站优化手段
应用到标签的伪属性,数据捕获的时候一定基于伪属性进行
imagePileline:专门用于二进制数据下载和持久化存储的管道类(图片下载)
source
:https://www.cnblogs.com/presleyren/p/12936553.html
使用 Google 的Chrome Devtools-Protocol(Chrome 开发工具协议)简称CDP。
通过这个命令,我们可以给定一段 JavaScript 代码,让 Chrome 刚刚打开每一个页面,还没有运行网站自带的 JavaScript
代码时,就先执行我们给定的这段代码。
那么如何在 Selenium
中调用 CDP
的命令呢?实际上非常简单,我们使用driver.execute_cdp_cmd
。根据 Selenium 的官方文档[2],传入需要调用的 CDP 命令和参数即可;
只需要执行一次,之后只要你不关闭这个driver开启的窗口,无论你打开多少个网址,他都会自动提前在网站自带的所有 js 之前执行这个语句,隐藏window.navigator.webdriver
。
完美隐藏window.navigator.webdriver
。并且,关键语句:
1 driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { 2 "source": """ 3 Object.defineProperty(navigator, ‘webdriver‘, { 4 get: () => undefined 5 }) 6 """ 7 })
虽然使用以上代码就可以达到目的了,不过为了实现更好的隐藏效果,大家也可以继续加入两个实验选项:
1 from selenium import webdriver 2 options = webdriver.ChromeOptions() 3 options.add_experimental_option("excludeSwitches", ["enable-automation"]) 4 options.add_experimental_option(‘useAutomationExtension‘, False) 5 driver = webdriver.Chrome(options=options, executable_path=‘./chromedriver‘) 6 driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { 7 "source": """ 8 Object.defineProperty(navigator, ‘webdriver‘, { 9 get: () => undefined 10 }) 11 """ 12 }) 13 driver.get(‘http://exercise.kingname.info‘)
这是close()的说明:
Closes the current window. ? 关闭当前窗口。
这是quit()的说明:
Quits the driver and closes every associated window. ? 退出驱动并关闭所有关联的窗口。
gb2312与gb2312 urlencode区别
1 import urllib 2 country = u‘中国‘ 3 country.encode(‘gb2312‘) 4 #-------‘\xd6\xd0\xb9\xfa‘ 5 urllib.quote(country.encode(‘gb2312‘)) 6 #--------‘%D6%D0%B9%FA‘
原文:https://www.cnblogs.com/xbhog/p/13335979.html