爬虫总结

一.requests模块重点梳理

(1)robots协议是什么?

Robots协议(也称为爬虫协议、爬虫规则、机器人协议等)也就是robots.txt,网站经过robots协议告诉搜索引擎哪些页面能够抓取,哪些页面不能抓取。python

Robots协议是网站国际互联网界通行的道德规范,其目的是保护网站数据和敏感信息、确保用户我的信息和隐私不被侵犯。因其不是命令,故须要搜索引擎自觉遵照。web

(2)列举您使用过的python网络爬虫所用到的网络数据包

requests, urllib面试

(3)http、https协议有什么区别?

http协议是超文本传输协议,被用于在web浏览器和网站服务器之间传递信息。http协议工做是以明文方式发送内容,不提供任何形式的数据加密,而这也是很容易被黑客利用的地方,若是黑客截取了web浏览器和网站服务器之间的传输信息,就能够直接读懂其中的信息,所以http协议不适合传输一些重要的、敏感的信息,好比信用卡密码及支付验证码等。ajax

安全套接字层https协议就是为了解决http协议的这一安全缺陷而出生的,为了数据传输的安全,https在http的基础上加入了ssl协议,ssl依靠证书来验证服务器的身份,为浏览器和服务器之间的通讯加密,这样的话即便黑客截取了发送过程当中的信息,也没法破解读懂它,咱们网站及用户的信息便获得了最大的安全保障。redis

(4)你写爬虫的时候都遇到过什么反爬虫措施,你是怎么解决的?

  • 经过headers反爬虫;数据库

  • 基于用户行为的发爬虫:同一IP短期内访问的频率;json

  • 动态网页反爬虫(经过ajax请求数据,或者经过JavaScript生成);浏览器

  • 验证码安全

  • 数据加密

解决途径:

  • 对于基本网页的抓取能够自定义headers,将header随request一块儿发送(通常是User-Agent,Cookie)

  • 使用IP代理池爬取或者下降抓取频率

  • 使用selenium + phantomjs 进行抓取抓取动态数据,或者找到动态数据加载的json页面

  • 使用打码平台识别验证码

  • 对部分数据进行加密的,可使用selenium进行截图,使用python自带的pytesseract库进行识别,可是比较慢最直接的方法是找到加密的方法进行逆向推理。

(5)POST与GET的区别

  • GET数据传输安全性低,POST传输数据安全性高,由于参数不会被保存在浏览器历史或web服务器日志中;

  • 在作数据查询时,建议用GET方式;而在作数据添加、修改或删除时,建议用POST方式;

  • GET在url中传递数据,数据信息放在请求头中;而POST请求信息放在请求体中进行传递数据;

  • GET传输数据的数据量较小,只能在请求头中发送数据,而POST传输数据信息比较大,通常不受限制;

  • 在执行效率来讲,GET比POST好

(6)为何会用到代理?

网站的反爬虫策略会检测到同一个IP访问次数频率过快,从而禁止该IP的访问。所以爬虫过程当中须要IP代理避免该问题。

二. 数据解析重点梳理

(1)使用正则对页面源码数据进行解析时,应该使用re.S仍是Re.M?

re.S为单行解析,解析的源码数据中能够有换行符,re.S会做用到整个被视为一个大字符串的页面源码数据中。re.M为多行解析,会将正则做用到源码的每一行中。在实战中使用的是re.S。

(2)xpath插件的做用?

能够在浏览器中直接校验xpath表达式,校验成功后再将xpath做用到程序中。

(3)xpath表达式回顾

//div[@class=‘xxx’]         # 属性定位

//div[@id=’xxx’]/a[2]/span  # 层级索引定位

//a[@href=’’and @class=’xxx’]   # 逻辑运算

//div[contains(@class,’xx’)]    # 模糊匹配

//div[starts-with(@class,’xx’)] # 模糊匹配

/div/text()  or /div//text()    # 取文本

/@属性    # 取属性

(4)bs4解析经常使用方法回顾

find()      # 找到第一个符合要求的标签

find_all()  # 找到全部符合要求的标签

select()    # 根据选择器找到符合要求的标签

div a ul li # 多层级选择器

div>a>ul>li # 单层层级选择器

三.打码平台使用流程

  1. 对携带验证码的页面数据进行抓取

  2. 将页面中的验证码进行解析, 将验证码图片下载到本地

  3. 将验证码图片提交给打码平台进行识别, 返回识别后的结果

云打码平台使用:

  1. 在官网中进行普通用户和开发者用户注册

  2. 登陆开发者用户:

    a) 示例代码下载:开发文档 --> 调用示例及最新DLL --> PythonHTTP示例下载

    b) 建立一个软件:个人软件 --> 添加新的软件(后期会使用该软件的秘钥和id)

  3. 使用示例代码中的示例代码对保存本地的验证码进行识别

四.移动端数据爬取

博客地址:http://www.javashuo.com/article/p-poferjjp-bx.html

# 详情步骤请查看视频:
连接:https://pan.baidu.com/s/1BiNd3IPA44xGszN9n93_hQ 
提取码:6slk

1.fiddler的设置

  • 端口号和容许抓取其余机器上的数据包的设置

  • https数据包抓取的设置

2.fiddler证书下载

  • 保证手机和fiddler所在的机器处在同一网段下

  • 下载安全证书,且安装到手机上。在手机浏览器中录入fiddler机器的ip和fiddler的端口号进行证书的下载。

  • 下载成功后进行证书的安装

  • 详细步骤请参考 博客

3.局域网设置

  • 将手机的网络和端口号设置成fiddler电脑的ip和fiddler的端口号

  • 测试:
    • 开启fiddler,抓取手机请求的网络包

五.Scrapy重点回顾

1.持久化存储操做

(1)基于终端指令的持久化存储

scrapy crawl 爬虫名称 -o xxx.json
scrapy crawl 爬虫名称 -o xxx.xml
scrapy crawl 爬虫名称 -o xxx.csv

(2)基于管道的持久化存储

1. 将爬取到的数据封装在item对象中

2. 使用yield将item提交给管道

3. 在管道文件中的process_item方法中,将item中的数据进行持久化存储操做

面试题:若是最终须要将爬取到的数据值一份存储到磁盘文件,一份存储到数据库中,则应该如何操做scrapy?

  • 管道文件中的代码为:
#该类为管道类,该类中的process_item方法是用来实现持久化存储操做的。
class DoublekillPipeline(object):

    def process_item(self, item, spider):
        #持久化操做代码 (方式1:写入磁盘文件)
        return item

#若是想实现另外一种形式的持久化操做,则能够再定制一个管道类:
class DoublekillPipeline_db(object):

    def process_item(self, item, spider):
        #持久化操做代码 (方式1:写入数据库)
        return item
    
    
"""
须要注意的是, 在pipelines.py文件中, 若是pipeline要把该数据存储到不一样的数据库, 就须要在pipelines.py文件中建立多个类, item会在每个类中的process_item方法中进行传递(经过process_item方法中的return item), 所以除了最后一个类的process_item方法能够不return item外, 其他的类都必须return item
"""
  • 在settings.py开启管道操做代码为:
#下列结构为字典,字典中的键值表示的是即将被启用执行的管道文件和其执行的优先级。
ITEM_PIPELINES = {
   'doublekill.pipelines.DoublekillPipeline': 300,
    'doublekill.pipelines.DoublekillPipeline_db': 200,
}


"""
上述代码中,字典中的两组键值分别表示会执行管道文件中对应的两个管道类中的process_item方法,实现两种不一样形式的持久化操做。
"""

2.基于scrapy的请求

(1)手动get请求发送

yield scrapy.Request(url,callback)

# 参数说明:
url: 请求的url
callback: 指定方法对请求到的页面进行解析操做

(2)post请求发送

重写父类的start_request方法,该方法会被调度器默认调用,在该方法中能够经过yield scrapy.FormRequest(url,callback,formdata)进行post请求发送。

  • 参数formdata为post请求携带的参数,类型为字典。

(3)何时会须要使用请求传参?

  • 当需求中须要解析的数据值不在同一个页面中时, 必须用请求传参进行处理.

  • 实现方式:yield scrapy.Request(url,callback,meta), 使用meta参数能够将item对象传递给callback指定的回调方法中. meta为字典类型.

(4)UA池和代理池

博客地址: http://www.javashuo.com/article/p-mbfwxnkq-dd.html

  • 使用UA池和代理池的目的:
    • 目的在于防止爬取网站的反爬虫策略
  • UA池操做流程:
    • (1) 在下载中间件中拦截请求
    • (2) 将拦截到的请求的请求头信息中的UA进行篡改假装
    • (3) 在配置文件中开启中间件
  • 代理池操做流程:
    • (1) 在下载中间件中拦截请求
    • (2)将拦截到的请求ip修改为某一代理ip
    • (3)在配置文件中开启中间件

(5)scrapy中selenium的应用

博客地址: https://www.cnblogs.com/bobo-zhang/p/10013045.html

原理分析

当引擎将国内板块url对应的请求提交给下载器后, 下载器进行网页数据的下载, 而后将下载到的页面数据封装到response中, 提交给引擎, 引擎将response再转交给Spiders. Spiders接受到的response对象中存储的页面数据里是没有动态加载的新闻数据的, 要想获取动态加载的新闻数据, 则须要在下载中间件中对下载器提交给引擎的response响应对象进行拦截, 且对其内部存储的页面数据进行篡改, 修改为携带了动态加载出的新闻数据, 而后将被篡改的response对象最终交给Spiders进行解析操做.

selenium在scrapy中的使用流程

  • 重写爬虫文件的构造方法, 在该方法中使用selenium实例化一个浏览器对象(由于浏览器对象只须要被实例化一次, 因此选择把它写在构造方法__init__中)

  • 重写爬虫文件的closed(self, spider)方法, 在其内部关闭浏览器对象. 该方法是在爬虫结束时被调用的.

  • 重写下载中间件的process_response方法, 让该方法对响应对象进行拦截, 并篡改response中存储的页面数据.

  • 在配置文件中开启 下载中间件.

(6)分布式爬虫实现步骤:

  • 导包
from scrapy_redis.spiders import RedisCrawlSpider
  • 将爬虫类的父类修改为RedisCrawlSpider

  • 将起始url列表注释, 添加一个redis_key(调度器队列的名称)的属性

  • 对redis数据库配置文件redisxxx.conf进行配置:
    • # bind 127.0.0.1
    • protected-mode no
  • 对项目中settings进行配置

    • a) 配置redis服务器的ip和端口号:

      • REDIS_HOST = 'redis服务的ip地址'
        REDIS_PORT = 6379
        # REDIS_PARAMS = {‘password’:’123456’}
    • b) 配置使用scrapy-redis组件中的调度器:

      • # 使用scrapy-redis组件的去重队列
        DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
        
        # 使用scrapy-redis组件本身的调度器
        SCHEDULER = "scrapy_redis.scheduler.Scheduler"
        
        # 是否容许暂停
        SCHEDULER_PERSIST = True
    • c) 配置使用scrapy-redis组件中的管道:

      • ITEM_PIPELINES = {
          #'wangyiPro.pipelines.WangyiproPipeline': 300,
          'scrapy_redis.pipelines.RedisPipeline': 400,
        }
    • d) 开启redis数据库的服务: redis-server 配置文件

    • e) 执行爬虫文件: scrapy runspider wangyi.py

    • f) 向调度器的队列中扔一个起始url:

      - i. 开启redis客户端
      
      - ii. lpush 爬虫文件名称 起始url

六.常见问题

1.如何显著提高爬虫的效率

1. 使用性能更好的机器

2. 使用光纤网络

3. 多进程

4. 多线程

5. 分布式

2.基于requests模块的多线程爬取

基于requests模块的多线程爬取建议你们使用`multiprocessing.dummy.pool线程池, 爬取效率会显著提高.

代码展现:

import requests
from bs4 import Beautiful
#导入线程池
from multiprocessing.dummy import Pool

pool = Pool()#实例化线程池对象
#发起首页请求
page_text = requests.get(url='xxx')
#使用bs4解析首页中全部的a标签
soup = Beautiful(page_text)
a_list = soup.select('a')
#将a标签的href属性值和域名拼接,造成完整的url
url_list = ['www.xxx.com/'+url['href'] for url in a_list]
#封装请求函数,该函数能够获取请求对应的页面数据
request_page_text = lambda link:requests.get(link).text

#使用线程池的map方法异步进行请求发送,切获取响应回来的页面数据
page_text_list = pool.map(request_page_text, url_list)

#使用线程池异步进行解析操做
get_data = lambda data:parse(data)
pool.map(get_data, page_text_list)

#数据解析方法
def parse(data):
    pass

3.如何提高scrapy的爬取效率

(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.

4.经常使用的代理ip网站, 及其代理IP的价格

i. 全国代理IP网:

  • 动态代理IP

  • 长效代理IP

ii. 西祠代理网:

  • 套餐价格:

iii. 快代理网:

  • 套餐价格:

七. 简历中爬虫项目的编写

1.关于爬取数据类型的问题

常见的爬取数据类型

  • 电商类的商品信息
    • a) 数据来源网站: 京东, 天猫
  • 资讯类的新闻信息
    • a) 网易新闻, 腾讯新闻, 今日头条等
  • 音乐类的歌词、歌名、做者信息
    • a) 网易音乐, qq音乐等
  • 医疗器械类的参数信息
  • 气象类的天气信息

2.爬取数据量级的问题

  • 针对于百万量级的数据:
    • a) 基于requests模块进行爬取, 时长为2小时左右
    • b) 基于分布式机群(3台), 时长为0.3小时左右
    • c) 通常公司生产环节中, 数据量过百万, 则通常会使用分布式进行数据爬取

3.简历中相关爬虫项目(Demo)

(1)项目名称: 潮流穿衣搭配数据采集

(2)项目描述:

本项目采用scrapy框架对爱搭配网和穿衣打扮网等网站导航页下全部大类、小类中的相关子连接, 以及连接页面的相关内容进行爬取, 将数据写入数据库, 提供给公司作参考数据.

(3)责任描述:

a. 负责信息数据的爬取

b. 负责分析数据爬取的过程

c. 负责分析网站的反爬技术, 并提供反反爬策略

d. 采用线程池进行数据爬取, 采集了13w条数据

e. 负责将采集到的数据进行数据分析整理

4.项目名称: xxx新闻推荐系统数据采集

(1)项目描述:

本项目采用基于RedisCrawlSpider的分布式爬虫, 对网易新闻、头条、新浪新闻等网站进行大类板块下新闻资讯数据的爬取, 将爬取到的数据调用百度AI接口进行关键字提取和文章分类检索. 设计库表进行数据存储.

(2)责任描述:

a. 搭建5台分布式机群进行新闻数据爬取

b. 分析数据爬取过程, 设计反反爬策略

c. 将分布爬取到的近30w条数据进行数据清洗和异常值过滤

d. 调用百度AI对新闻数据进行关键字提取和文章分类

相关文章
相关标签/搜索