l 爬虫概述:了解什么是爬虫
l 爬虫优势:知道爬虫用在什么地方
l 爬虫实现方式:了解实现爬虫用到的各种技术
l 爬虫的分类:了解爬虫工作相关的一些(不同爬虫)区别
l 第一个操作程序:采集新浪社区新闻首页数据
l 爬虫请求操作:伪造请求[技术实现]
l 爬虫请求操作:模仿用户行为[社会工程学]
l 爬虫请求操作:请求隐藏[代理]
1. 软件安装
python2.7开发环境
学生端程序
pycharm开发工具
虚拟环境:virtualenv
每个项目一个独立的虚拟环境
方便项目部署时收集开发环境中的模块:pip freeze>pkg.list
1. 什么是爬虫[爬虫概述]
爬虫:Spider
爬虫-> 蚂蚁下载软件 | 迅雷下载 | ..
小脚本程序,从网络上采集要下载的数据的资源->完成高速下载
爬虫-> 度娘、谷哥..搜索引擎
搜索引擎-> 采集数据的程序-> 从网络上搜索数据提供给搜索引擎使用
百度-> 关键词-> 包含该关键词的所有网页
公司|企业数据进行深度分析-> 数据挖掘-> 大数据-> 大量的数据处理
大量的数据从哪里来?
数据的重要性
软件:用来解决生活中的问题!
解决生活中的问题,核心思想?
核心:处理数据!
操作:增删改查[CRUD]
数据从哪里来?
数据:都是从生活中来的!
生活中的数据,怎么到自己需要的地方[数据库]
n 手工采集:可以采集数据,但是操作效率低下
n 内部数据:公司内部数据,权限范围内尽情使用!:数据有限、较强的针对性
n 数据交易:数据采集迅速、费用较高;-- 数据不能定制化!
n 爬虫采集:定向数据采集;成本较高、数据定制化很强、数据针对性很强
u 搜索引擎:不是我们的重点!
u 定向爬虫:我们工作的重点!-- 开启了保护和反保护的斗争
u 爬虫[采集数据]和反爬虫[防止恶意采集数据]
2. 爬虫的采集方式——分类
通用爬虫:一般用在搜索引擎中:针对所有数据进行广泛采集[广度]
搜索引擎作为爬虫~必须遵守爬虫采集数据的约定协议
民间组织约定的爬虫采集数据协议:ROBOT协议
爬虫:好的一面~可以将自己的网站让更多的人通过搜索引擎访问~网络流量分流
ROBOT协议:是一种约定的规范;针对通用爬虫进行的数据采集限制
聚焦爬虫:也成为定向爬虫,针对目标数据进行定向数据采集[深度]
每个数据采集任务,都可能要开发一套新的项目 :程序开发密集度
数据采集定向采集[在不违反中华人民共和国宪法的前提下]可以针对任何数据进行采集(一般正规的公司安排的数据采集任务基本都是合法的->公司承担责任):数据定向性
技能要求:上手快,入门简单,对数据的分析要求较高!
工作的重点:聚焦爬虫;工作的核心:采集数据;
PS:爬虫~是通过程序的方式,自动采集数据;程序操作比自然人的操作效率高出很多很多倍;所以如果一旦通过无限制的爬虫对网站发起请求,[爬虫的频繁请求让服务器资源迅速消耗,最终导致服务器内存不存或者其他后果!],网站很容易DDOS
DDOS[拒绝服务攻击]
3. 关于历史数据的处理
百度搜索-> 爬虫采集了网络中的大部分网站的数据-> 其他人通过搜索网站,可以直接在搜索页面中进入指定的网站
PS:某个网站进行了更新,百度以前搜索到的页面数据变化了!数据不一致~
百度爬虫对原来采集过的数据要实时进行更新
增量爬虫:需要实时对历史采集数据进行更新[历史数据会发生变化]
股票数据采集-> 采集了过去10年每一个交易日的股票历史数据,方便对未来的数据进行分析处理
PS:需要对历史数据进行更新吗?
累积爬虫:历史数据不会发生变化,一旦数据执行完成,数据就是固定的
程序开发:第一个爬虫程序
开发环境:python2.7
开发工具:pycharm
python2和python3区别
编码:Python2使用的是ascii编码;python3使用的是unicode编码
UTF-8-> unicode trasfer format 8bit 主持中文
ascii-> 不支持中文 -> ANSI->扩展ANSI->..
表示英文->1个字符->2个字节->16位
表示汉字->2个字符->4个字节->32位->国家标准编码GB2312->GBK->GB18030
英文-中文,编码方式可能不同,就会造成乱码的问题!
解决乱码的问题-> 不论什么字符->转换成字节->按照指定的编码转换成字符
开始开发:
python2使用的是ascii编码,所以源代码文件都不支持中文
源代码代码中第一行的位置,添加支持中文的注释
#-*- coding:utf-8 -*-
#coding:utf-8
#..
为什么要使用python2
python主要的版本1.x,2.x,3.x
目前web市场主流版本:3.x[网站开发-文本字符数据的交互,配合二进制文件的处理,更多的会使用到的比较通用的unicode字符]
爬虫工作主流版本:2.x[都是从网络上采集数据,采集的数据文本数据、二进制数据,为了方便并且统一的进行采集数据的处理,使用python2操作更加灵活]Python2在爬虫方向支持的第三方模块更多!
程序开发
|
采集到新浪网网页数据
有用?采集首页中各个模块的链接地址和名称,方便进行该模块二次数据采集
没用?其他数据~不需要
采集网页的源代码,为什么要用爬虫程序?鼠标右键查看源代码可以完成!
为什么要用爬虫{爬虫的优势?!}
有那么多的工具[迅雷、旋风、百度云、整站下载工具等等],为什么要用爬虫!
[刘文超]
[刘锐红]
最近上映了妇联3->要看这部电影,怎么办?--下载工具
最近要看一本小说->[阴阳师]-> 怎么办?--搜索引擎-搜索资源-下载工具
要获取某个网站上的大部分电商商品[名称、价格、描述]->怎么办-爬虫程序自动采集
要获取多个新闻网站上,最近1个月的所有新闻数据[标题、发布时间、编辑人、内容]->怎么办——爬虫程序自动采集
爬虫程序—发送请求给服务器,获取服务器的数据
爬虫程序~发送的请求什么样的?Spider Request
浏览器程序~发送的请求什么样的?Browser Request
这两个请求,有什么区别?
了解清楚有什么区别~才能掌握好爬虫程序的请求[伪装浏览器请求]
(1) 抓包工具
网络上流行的抓包工具有很多,wareshark、burpsuits、fiddler、F12窗口
浏览器发送的请求:F12窗口,直接查看请求信息
程序发送的请求:怎么看PYTHON爬虫程序发起请求的信息
了解请求程序发送请求和浏览器发送请求的区别:才能更加完美的伪造请求
(2) 请求伪造
请求对象:获取一个请求对象,通过请求对象设置用户代理[User-agent]请求头
请求头中的K=V数据:K键值~单词首字母必须大写
请求对象:urllib2.Request对象
通过对urllib2.Request对象的设置,完成请求的伪造操作
隐藏用户:使用代理IP进行请求操作
正向代理:代理客户端发起请求,向服务器请求数据;隐藏客户端信息
反向代理:代理的服务端;隐藏真实服务器信息
都有什么样的代理:免费代理、收费代理 -- [透明代理|匿名代理|高匿代理]
python爬虫中,怎么使用这些代理
默认情况下,urllib2爬虫程序直接通过urlopen()发送请求!
è 查询对应的资料[官网资料|总结的资料|国外资料]
è 查看底层代码,模仿还原
采集:百度图片~美女图片
1. 爬虫的理论知识
a) 什么是爬虫?
b) 爬虫的分类
i. 通用爬虫 VS 聚焦爬虫
ii. 累积爬虫 VS 增量爬虫
c) 爬虫的实现
i. Java|Python|PHP|C++|C#|Ruby|Delphi|..
ii. python:更加专业
iii. urllib2基础->requests->scrapy->分布式
2. 爬虫的操作
a) urllib2底层数据采集urlopen()函数
b) 伪造请求:伪装浏览器请求
i. 请求对象:请求头数据、请求体数据、请求方式..
ii. 请求头中的User-agent设置,完成浏览器请求的伪装
iii. 请求对象:urllib2.Reuqest对象
c) 模仿用户行为:只有在特殊的情况下才会使用
i. 随机休眠严重影响爬虫采集数据的效率
d) 隐藏客户端:使用IP代理,代理真实客户端完成对服务器数据的访问
i. 免费代理|收费代理
ii. 正向代理[代购]|反向代理[代理商]
iii. urlopen底层操作
1. 操作对象:urllib2.ProxyHandler({..})
2. 开锁对象:urllib2.build_opener(handler)
3. 发送请求:res = opener.open(url)
''' url:https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E7%BE%8E%E5%A5%B3&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word=%E7%BE%8E%E5%A5%B3&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&cg=girl&pn=240&rn=30&gsm=f0&1527500554991= pn = 0 表示从第几个开始 rn = 表示往后显示多少个,最大数位:60 图片url :"thumbURL":https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=983383169,2627637251&fm=27&gp=0.jpg 正则:r'https:\/\/([a-z0-9]+\.)+([a-z]+\.)+([a-z]+\/)+([a-zA-Z0-9]+\/)+([a-z]+\/)+(u=[0-9]{10},[0-9]{10})(&fm=27&gp=0)\.jpg$' reg = re.compile('"thumbURL": "(https.*?jpg)"', ) ''' import time, random from urllib2 import Request, ProxyHandler, build_opener, urlopen import re #定义请求的url base_url = "https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E7%BE%8E%E5%A5%B3&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word=%E7%BE%8E%E5%A5%B3&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&cg=girl&pn={}&rn=60&gsm=f0&"+str(int(time.time()*1000))+"=" # 定义User-ahent base_url_list = [base_url.format(n) for n in range(0,360,60)] useragent = [ 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;', 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1', 'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11', ] for index,next_url in enumerate(base_url_list): # 定义请求头 headers = { # 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', # 'Accept-Encoding': 'gzip, deflate, br', # 'Accept-Language': 'zh-CN,zh;q=0.9', # 'Cache-Control': 'max-age=0', # 'Connection': 'keep-alive', 'Cookie': 'BDqhfp=%E7%BE%8E%E5%A5%B3%26%260-10-1undefined%26%260%26%261; BAIDUID=0F629939E752EC3B893185C15F35C5C8:FG=1; BIDUPSID=0F629939E752EC3B893185C15F35C5C8; PSTM=1527488835; BDRCVFR[7JA7KA5iDWT]=mk3SLVN4HKm; H_PS_PSSID=; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; PSINO=5; BDRCVFR[dG2JNJb_ajR]=mk3SLVN4HKm; BDRCVFR[X_XKQks0S63]=mk3SLVN4HKm; firstShowTip=1; indexPageSugList=%5B%22%E7%BE%8E%E5%A5%B3%22%5D; cleanHistoryStatus=0', 'Host': 'image.baidu.com', # 'Upgrade-Insecure-Requests': '1', 'User-agent': random.choice(useragent) } # print headers # 构建请求对象 request = Request(base_url,headers = headers) # 自定义代理操作对象 proxy_handler = ProxyHandler({'http':'60.176.232.13:6666'}) # 构建一个opener对象 proxy_opener = build_opener(proxy_handler) # 使用自定义opener访问服务器数据,得到相应 response = proxy_opener.open(request) response = urlopen(request) content = response.read() # print content # 通过正则匹配图片url地址 print('>>>>>>>>>>>>>>>获取%d页图片url'%index) ret_list = re.findall('"thumbURL":"(https.*?jpg)"',content) print ('获取第%d页的图片'%index) for num,ret in enumerate(ret_list): headers = { # 'Accept': 'text/html, application/xhtml+xml, application/xml;q = 0.9, image/webp, image/apng, */*;q = 0.8', # 'Accept - Encoding': 'gzip,deflate,br', # 'Accept - Language': 'zh - CN, zh;q = 0.9', # 'Cache - Control': 'max - age = 0' # 'Connection': 'keep - alive', 'Host': 'ss1.bdstatic.com', 'If - Modified - Since': 'Thu, 01 Jan 1970 00:00:00 GMT', 'If - None - Match': '8bbc885d21ace8283d7f41cf778c8fb3', 'Upgrade - Insecure - Requests': '1', 'User - Agent':random.choice(useragent), } request = Request(ret, headers=headers) # 自定义代理操作对象 proxy_handler = ProxyHandler({'http': '60.176.232.13:6666'}) # 构建一个opener对象 proxy_opener = build_opener(proxy_handler) # 使用自定义opener访问服务器数据,得到相应j response = proxy_opener.open(request) response = urlopen(request) print('>>>>>>>>>>>开始保存图片' + str(index)+'-'+str(num)) with open( './images/'+str(index)+'-'+str(num)+".jpg", "wb") as f: f.write(response.read())