第一章爬虫介绍
- 爬虫的分类
- 通用爬虫:爬取一整张页面
- 聚焦爬虫:爬取页面中局部的内容
- 增量式爬虫:去重【重要】
- robots协议
- 反爬机制
- 针对门户网站
- 反反爬策略
- 正对爬虫
第二章http和https协议
- 协议概念:基于clinet和server之间的一种通信协议
- 常用请求头信息:
- User-Agent:请求载体的身份标识
- Connection:
- 常用响应头信息: Content-Type:
- 三种加密方式:
- 对称秘钥加密:
- 非对称秘钥加密:
- 证书加密:
第三章 requests模块
- 请求数据方式(两个方法+四种方式)
- get请求
- post请求
- 基于Aajx的get/post请求,返回的基本都是json数据
- 【重点注意】url和携带的参数
- 用到的参数:
- url
- headers
- 参数:get方法:parma;post方法:data
- 处理代理IP:proxy
- UA伪装(反反爬策略)
- 爬取基于ajax请求数据的流程
- 使用抓包工具捕获ajax请求对应的数据包
- 从数据包中提取url和对应的请求参数
- 请求的发送(处理参数)
- 获取json格式响应数据 response.json()
- 爬取图片数据的方式
- with open方法
- urllib.request.urlretrive(url,filename)
- 实现模拟登陆
- 如何实现模拟登录:登录后发起post请求,获得数据包url及参数
- 为什么模拟登录
- 获取cookie
- 需要获取基于用户的用户信息
- 处理cookie(反反爬策略)
- requests.Session()返回session对象,如果有cookie的话,将cookie自动存储到session中
- 验证码识别(反反爬策略)
- 使用云打码平台处理验证码
- 设置代理(反反爬策略)
- get(proxies = {'http/https':'ip:port'} )
- 使用线程池(multiprocessing.dummy.Pool)实现数据爬取
- pool = Pool(5) # 开启5个线程
- list = pool.map(func,list) # func异步对list中的元素进行操作
第四章 数据解析
- 正则解析
- xpath解析
- 解析原理:
- 标签的定位
- 取数据
- xpath插件
- /相对路径 //绝对路径
- /text()指定文本 //text()所有文本
- li.xpath('./')
- 数据加密-煎蛋网(反反爬策略)
- 分析js使用bytes64解密
- 【重点】如何判断页面数据是否为动态加载出来的
- 抓包工具中response中存放的数据才是我们用requests请求到的数据,response中源码数据与elements中显示的数据不一样
- 爬取全国所有城市名称(xpath表达式的特殊使用 | )
- 或运算符 | :匹配多个xpath表达式
- 常见错误处理:HTTPConnectionPool(host:XX)Max retries exceeded with url
- ip被禁,连接池资源满了,请求频率过高
- 解决方法:
- Connection:'close'
- 使用代理ip
- sleep
- 解析原理:
- bs4解析
- soup.elementName# 定位到第一次出现的该标签
- find()返回单数 findall()返回复数
- select('选择器')层级选择器
- 取属性
- .string直系文本内容
- .text;.get_text()非直系全部内容
- ['href']定位改标签并去除属性值
第五章 验证码处理
第六章 动态数据加载
- 通用方法捕获动态加载的数据
- selenium+phantomjs:
- 注意使用浏览器的驱动程序
- phantomjs既是浏览器也是浏览器的驱动,可以使用在无界面浏览的环境中
- get()发请求
- find_xxx标签定位
- click点击操作
- send_keys()文本框中出入数据
- excute_script('js')执行js代码
- switch_to().frame(id):iframe 定位iframe的id
- selenium+phantomjs:
第七章 移动端数据爬取
- 需要的登录的软件,爬取数据时很难的
第八章 scrapy框架基础+持久化存储
- spider文件
- name 爬虫文件的名称,爬虫文件的唯一标识
- start_urls 起始url列表
- parse 解析数据
- 持久化存储方式:
- 基于终端指令:将parse方法的返回值存储到本地,文件类型有要求
- 基于管道:
- 获取解析的数据,response.xpath进行数据解析
- 将解析的数据封装到item类型的对象中
- 向管道提交item:使用yield
- 在管道的process_item方法中执行持久化存储操作
- 在配置文件中开启管道
- 注意:
- process_item会被调用多次,当爬虫文件每执行一个yield item时,都会执行process_item文件
- process_item的返回值:将item传递给下一个管道类
第九章 递归解析和post请求
- 递归解析:手动请求发送
- 为什么使用手动请求发送
- 分页请求操作
- yield scrapy.Request(url,callback)
- 为什么使用手动请求发送
- post请求【基本不发送post请求】
- 重写start_request()方法:(自动处理cookie)
- yield scrapy.FormRequest(url,callback,formdata)
第十章 日志等级和请求传参
- 日志等级
- setting文件中添加
- LOG_LEVEL
- LOG_FILE
- 什么时候会用到请求传参:当解析的数据不在同一张页面的情况下.
- scrapy.Request(url,callback,meta={})
- response.meta['key']
- setting文件中添加
第十一章 UA池和代理池
- 下载中间件:拦截请求和响应
- 拦截请求
- 处理UA
- process_request(request):
request.headers['User-Agent'] = 'xxxx' UA池
- 拦截响应
- process_response
- 拦截异常
- process_exception:
- request.meta['proxy'] = 'http://ip:port' 代理池;当请求发生异常时才处理ip
第十二章 scrapy中selenium的应用
- spider的init构造方法中实例化一个浏览器对象(bro)
- spider的closed(self,spider)执行关闭浏览器操作
- 在中间件的process_response执行浏览器自动化的操作(get,page_source)获取页面源码数据
- 实例化一个新的响应对象(scrapy.http.HTMLResponse(body=page_source))
- 返回响应对象
- 在配置文件中开启中间件
第十三章 全站数据爬取
- CrawlSpider:scrapy genspider -t crawl xxx www.xxx.com
- 连接提取器:LinkExtactor(allow='xxxx')
- 规则解析器:Rule(link,callback,follow=True)
第十四章 分布式爬虫
第十五章 增量式爬虫
数据分析
- numpy
- 切片 arr[index,col]
- 变形:reshape()
- 级联:concatnate()
- 切分:spilt
- 排序:sort
- Series
- 过滤空值
- 去重:unique()
- DataFrame
- 创建
- 索引
- 取列:
- 取行:
- 取元素:
- 切片:
- 切列:df.loc[:,col]
- 切行:df[:]
- 空值检测和过滤
- 数据清洗的4种方式:将控制所对应的行删掉;将控制做覆盖;将重复行删掉;将异常值进行检测过滤
- 空值检测函数:
- isnull.any(axis) notnull.all(axis)
- 空值过滤思路:
- 将检测函数的结果直接作为df的索引值,将空值所在的行或列过滤掉;
- 空值过滤函数:
- dropna(axis=0) 直接进行检测和过滤,axis的0/1与其他函数相反
- 检测重复行:
- drop_duplicated(keep) 检测到哪些行是重复的,参数keep为保留,
- 覆盖控制:
- fillna(method,axis) 方法method=ffill/bfill向前或向后填充
- 过滤重复行:
- 随机取样:
- take([3,1,2,0],axis=1) 第一个参数放行/列的隐式索引的排序规则,axis的0/1与其他函数相反
- random.permutaion(5) 生成随机序列,作为take中的参数一,配合take使用
- 级联机制:concat(),保留控制outer
- 合并机制:merge,数据的合并
- 替换:replace(to_replace,value)
- 映射:map()做映射或充当运算工具:Series.map(func);apply()比map()效率高
- 分组:df.groupby(by)['xxx'].mean()
- 分组聚合:
- df.groupby(by)['xxx'].apply(func)
- 条件查询函数:df.query('字符串形式的条件')