爬虫初步
爬虫概念
都有哪些语言可以实现爬虫
(1)php, 号称世界上最好的语言,可以实现爬虫,但做的不好,天生对多进程和多线程支持的不好
(2)java,可以实现,而且做的非常好,是python爬虫最主要的竞争对手, 但语言不简洁,代码臃肿,重构成本高
(3)c、c++,也可以实现爬虫,非常强大,但是不是一个好的选择
(4)python,可以实现,号称世界上最优雅的语言,代码简洁,学习成本低,执行效率也好,而且还有一个非常强大的爬虫框架 scrapy
通用爬虫
例子:百度、谷歌、360、搜狗、必应等等,搜索引擎
工作:
(1)爬取互联网所有的数据
(2)对数据存储并且处理
(3)给用户提供检索服务
如何让百度抓取你的网站?
(1)静静地等待,百度会和DNS服务商合作
(2)主动提交自己的url
(3)在其它网站设置友情链接
我的网站不想让百度抓取?
君子协议,口头协议,robots协议
存放到网站的根目录下,限制搜索引擎可以爬取哪些,不可以爬取哪些
##### 如何提升网站排名(SEO)
(1)pagerank值排名,根据点击量、浏览量等,相当靠谱
(2)竞价排名
##### 通用爬虫缺点:
(1)抓取很多数据都是无效的
(2)不能根据自己的需求抓取数据
聚焦爬虫
根据自己特定的需求,来抓取指定的数据
如何实现聚焦爬虫?
网页的特点:
(1)网页都有自己唯一的url
(2)网页都是由html组成
(3)网页传输都是使用http、https协议
思路:
(1)给一个url
(2)模拟浏览器发送http请求
(3)从html结构中提取指定的数据,从字符串中根据规则提取指定数据
开发环境:
windows系统,python3.x(64位),sublime编辑器,pycharm,vscode
整体内容:
(1)涉及到的python库
urllib,requests,selenium,jsonpath,lxml等一些库
(2)解析内容
正则表达式解析,bs4解析,xpath解析,jsonpath解析
(3)采集动态html
DOM操作,动态的添加或者删除节点,selenium+phantomjs
(4)scrapy框架
异步高性能网络爬虫框架的学习
(5)scrapy-redis分布式部署
在scrapy的基础上,多了一套分布式部署的组件
(6)涉及到的爬虫-反爬虫-反反爬虫之间的斗争
反爬会伤害真实的用户,一般情况下,反爬也就这么两点:第一个UA,第二个封ip,第三个验证码,光学识别,打码平台
换思路解决问题:其他网站,手机端等
关于http协议
http和https的区别
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
加密:公钥私钥
客户端:123456用秘钥加密=======》服务端:用秘钥解密得到123456
秘钥相同称之为对称加解密
秘钥不相同称之为非对称加解密
客户端:123456用公钥加密=======》服务端:用私钥解密得到123456
http协议学习:
请求:包含请求行、请求头、请求内容
请求行:请求方式、请求资源、协议版本号
请求头:
accept:浏览器通过这个头告诉服务器,它所支持的数据类型
Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集
Accept-Encoding:浏览器通过这个头告诉服务器,支持的压缩格式
Accept-Language:浏览器通过这个头告诉服务器,它的语言环境
Host:浏览器通过这个头告诉服务器,想访问哪台主机
If-Modified-Since: 浏览器通过这个头告诉服务器,缓存数据的时间Referer:浏览器通过这个头告诉服务器,客户机是哪个页面来的 防盗链
Connection:浏览器通过这个头告诉服务器,请求完后是断开链接还是何持链接
X-Requested-With: XMLHttpRequest 代表是ajax的请求
响应:响应行、响应头、响应内容
响应行里面,常见的状态码
200:请求成功 处理方式:获得响应的内容,进行处理
301:请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源 处理方式:重定向到分配的URL
302:请求到的资源在一个不同的URL处临时保存 处理方式:重定向到临时的URL
304:请求的资源未更新 处理方式:丢弃,使用本地缓存文件
403:禁止 处理方式:丢弃
404:没有找到 处理方式:丢弃
405:请求方式不对
500:服务器内部错误 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。
响应头
Location: 服务器通过这个头,来告诉浏览器跳到哪里
Server:服务器通过这个头,告诉浏览器服务器的型号
Content-Encoding:服务器通过这个头,告诉浏览器,数据的压缩格式
Content-Length: 服务器通过这个头,告诉浏览器回送数据的长度
Content-Language: 服务器通过这个头,告诉浏览器语言环境
Content-Type:服务器通过这个头,告诉浏览器回送数据的类型
Refresh:服务器通过这个头,告诉浏览器定时刷新
Content-Disposition: 服务器通过这个头,告诉浏览器以下载方式打数据
Transfer-Encoding:服务器通过这个头,告诉浏览器数据是以分块方式回送的
Expires: -1 控制浏览器不要缓存
Cache-Control: no-cache
Pragma: no-cache
响应内容:html、css、js、图片
抓包工具
(1)谷歌浏览器自带抓包工具
右键开发者工具==》network
XHR: XMLHttpReqeust 前端要想发送ajax请求,通过它创建对象,发送请求
query_string_parameters : 请求字符串,get参数
formdata : 如果是post参数
(2)专业工具,fiddler,charles……
专业抓包工具,比谷歌强在了跳转的时候很多请求都能抓取到
前端要像发送ajax请求,创建对象调用对象方法需要通过XHR
urllib库
urllib库是自带的python库,模拟发送http请求
在python 2系列中使用:urllib urllib2
在python 3系列中使用:urllib
urllib库的使用
urllib.request 模拟发送请求
urlopen(url) : 向url发送请求,得到响应对象
1
2
3
4
5
6
7import urllib.request
url = 'http://www.baidu.com/'
response = urllib.request.urlopen(url)
print(response)
print(response.read())
可以看到结果如下:
print(response.read().decode(‘utf8’)):得到了二进制的格式,下一步我们需要使用decode将二进制格式解码为字符串格式
response属性和方法
print(response.url):拿到请求的url
print(response.headers):拿到请求的headers
print(response.status):拿到请求的状态码
urllib.parse: 处理参数或者url
urllib.error: 如何处理异常
保存到文件
将抓取的数据保存到文件有两种方式:
第一种方式:通过with打开文件(注意统一编码格式)
1
2
3
4
5
6
7# 将获取的响应内容保存到文件中
# with open('baidu1.html', 'a', encoding='utf8') as fp:
# fp.write(response.read().decode('utf8'))
# 以二进制的格式保存
# with open('baidu2.html', 'wb') as fp:
# fp.write(response.read())
第二种方式:直接以二进制的格式写入
1 | # 实现发送请求,将内容写入文件 |
- urlretrieve(url, filepath) : 向url发送请求,直接将响应写入到filepath中
编码:
字符串格式==》字节格式
encode(‘utf8’)
字节格式==》字符串格式
decode(‘gbk’)
爬取图片的保存
下载图片:得到图片的src属性,就可以将图片下载到本地
有两种方式,主要是对图片是做二进制的处理:
1 | import urllib.request |