目录
一、ROBOTS协议
网站通过robots协议告诉搜索引擎哪些页面可以爬取,哪些页面不能爬取,但他仅仅是互联网中的一般约定
如何查看网站的robots协议:在官网后面加上/robots.txt
例如:https://www.bilibili.com/robots.txt
协议毕竟只是协议,我们可以不遵守
二、http协议和https协议
为什么会有这种协议?--------> 方便不同的后端语言(框架)和前端对接
HTTP:超文本传输协议,默认端口号:80
HTTPS:HTTP+SSL(安全套接字层),即带有安全套接字层的超文本传输协议,默认端口号:443
HTTPS比HTTP更安全,但是性能更低
在我们去访问浏览器的时候,要遵循HTTP协议的请求报文
1.页面鼠标右键,点击检查(或者按快捷键F12)
2.选择Google浏览器自带的抓包工具,菜单栏的第三个Network
3.点击重新加载(即此时此刻再去请求一次百度首页)
4.选择第一个数据包www.baidu.com
Headers:
'''
General:
Request URL:https://www.baidu.com/ 我们输入的网址是www.baidu.com但浏览器在返送请求时会将url自动补全,当我们使用爬虫访问时,没有浏览器帮助我们自动补全url,所以注意要输入完整的url
Request Method:GET(请求方法)
Status Code:200 OK(状态码)
Remote Address:220.181.38.150:443(地址)
Referrer Policy:strict-origin-when-cross-origin
'''
'''
Response Headers:(服务器响应:不需要太多的关注)
Cache-Control: no-cache
Connection: keep-alive(这是长链接:访问一次很长时间不会断开 短链接:访问一次断开一次)
Content-Encoding: gzip(压缩格式)
Content-Type: text/html;charset=utf-8
Coremonitorno: 0
Date: Mon, 28 Jun 2021 03:52:36 GMT(日期:GMT格林尼治时间)
Server: apache
Set-Cookie: H_WISE_SIDS=110085_127969_174662_174665_175539_175667_175757_176399_176555_176590_176677_177168_177224_177281_177370_177383_177411_177630_177950_177971_178265_178327_178384_178493_178629_178704_178727_178896_178946_179005_179200_179258_179309_179313_179349_179400_179432_179483_179575_179640_179731_180093_180112_180120; path=/; expires=Tue, 28-Jun-22 03:52:35 GMT; domain=.baidu.com
Set-Cookie: bd_traffictrace=281152; expires=Thu, 08-Jan-1970 00:00:00 GMT
Set-Cookie: rsv_i=797cRTgnbrjTN%2BcRUdlRSAxTTXwMpetWn9J47lJp8qBynLyrZiR6LXRDRoNUX4ezaK662bl7W3MvaIaJAI%2B7O1cgnsUnpC0; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=764; path=/
Set-Cookie: eqid=deleted; path=/; domain=.baidu.com; expires=Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: BDUSS_BFESS=TNFaUExfmlBZzhVYklDNm1kRUN4aktDaWwxTUwxcHNVaWtTbWpKRUJ4cWphZjlnRVFBQUFBJCQAAAAAAAAAAAEAAADwfqczAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKPc12Cj3NdgN; Path=/; Domain=baidu.com; Expires=Thu, 26 Jun 2031 03:52:36 GMT; Max-Age=315360000; HttpOnly; Secure; SameSite=None
Set-Cookie: __bsi=; max-age=3600; domain=m.baidu.com; path=/
Strict-Transport-Security: max-age=172800
Traceid: 1624852356251415015411359252051301541648
Transfer-Encoding: chunked
Vary: Accept-Encoding
'''
'''
Requests Headers(爬虫作为请求的一方,这才是我们需要关注的地方):
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
(重点:cookie>会话记录,里面保存了客户端和服务端进行交互的记录,服务端产生之后发送给客户端的,下次发送请求的时候,需要把这个cookie带上,这里面保存着一些登录的客户信息)
Cookie: BIDUPSID=5C86C3A345E71E667845B24CF1E67F57; PSTM=1582554282; BD_UPN=12314753; BAIDUID=23067683930EF478ACC655262E9BAE53:FG=1; __yjs_duid=1_87d0c9f7af61c48570f2b985588a639f1618070691104; H_WISE_SIDS=107316_110085_127969_131423_155813_165136_166147_167729_169773_170817_170872_170935_171711_172118_172226_172468_172644_172828_173124_173413_173594_173601_173610_173615_173774_173832_174192_174197_174324_174432_174520_174598_174638_174670_174807_174855_174909_175043_175216_175365; MSA_WH=543_634; BDUSS=TNFaUExfmlBZzhVYklDNm1kRUN4aktDaWwxTUwxcHNVaWtTbWpKRUJ4cWphZjlnRVFBQUFBJCQAAAAAAAAAAAEAAADwfqczAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKPc12Cj3NdgN; BDUSS_BFESS=TNFaUExfmlBZzhVYklDNm1kRUN4aktDaWwxTUwxcHNVaWtTbWpKRUJ4cWphZjlnRVFBQUFBJCQAAAAAAAAAAAEAAADwfqczAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKPc12Cj3NdgN; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDRCVFR[-HoWM-pHJEc]=mk3SLVN4HKm; BD_HOME=1; H_PS_PSSID=34132_33763_31253_34072_33607_34106_34135_26350_22160; delPer=0; BD_CK_SAM=1; PSINO=1; COOKIE_SESSION=43756_0_6_6_17_6_1_0_6_5_0_1_43362_0_1_0_1624850020_0_1624850019%7C9%23350745_18_1620652952%7C9; ab_sr=1.0.1_ZTk2Y2I1NTQ3OWE0NmI0ZDUzOGMxODhjZjgwMmVjZDg2M2VkYTZhMmYzODFhMzhhZjhlNDdiNjBmODRmZWFiNDQ1ZDNjYTA2ZDAwYWNiODMyN2U0OTZlNTY4ODA4Yjc0N2YwOWVlODk0MzBjNWEzYWM1NWMwMDRjZTI2NWMyZmRiYzk4NjNjYzRkMjdiZDJhYzRlYzMxZDk0Y2E3MjQyYg==; H_PS_645EC=0ef1g2VovwqBLfgDpWv9db32uuMtFTcE6B0IudPXlRtEKjUQ%2F%2BLgCiqXC3c; BA_HECTOR=ah2g8h8hah8l2104991gdihrs0q
Host: www.baidu.com
(重点:Referer>跳转信息,记录当前页面是从哪个页面跳转过来的)
Referer: https://www.baidu.com/s?ie=UTF-8&wd=hao123
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
(重点:User-Agent>用户代理,访问者的身份,内容包括电脑信息和浏览器信息)
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Mobile Safari/537.36
'''
Preview:预览效果
Response(我们所关心的):响应的数据(代码)
Initiator:不关心
Timing:不关心
三、字符串的编码和解码
python3中两种字符串类型:
1.str:unicode的呈现形式
2.bytes:字节类型,互联网上数据都是以二进制的方式(字节类型)传输的
大部分情况下,我们需要爬取的都是文本数据。数据在网络传输中,基本都是以字节类型呈现的,python只能操作python类型的数据,所以我们就需要把这种类型的数据转化为python能够操作的类型数据
python的字符串string > 字节bytes:encode(编码)
string_ = 'abcd1234,.?!'
print(string_, type(string_)) # abcd1234,.?! <class 'str'>
bytes_ = string_.encode()
print(bytes_, type(bytes_)) # b'abcd1234,.?!' <class 'bytes'>
字节bytes > python的字符串string:decode(解码)
bytes_ = b'abcd1234,.?!'
print(bytes_, type(bytes_)) # b'abcd1234,.?!' <class 'bytes'>
string_ = bytes_.decode()
print(string_, type(string_)) # abcd1234,.?! <class 'str'>
图片、视频、音频都是bytes类型的格式,不需要解码成字符串string类型的,直接保存就可以
四、requests模块
requests模块是用来发送网络请求的
# 导入发送网络请求的模块
import requests
# 添加程序入口(模块和包的部分)
if __name__ == '__main__':
# 1.确认目标的url(地址)
url_ = 'https://www.baidu.com/' # url一定要完整
# 2.发送网络请求获取响应
response_ = requests.get(url_)
print(response_) # <Response [200]>响应对象,状态码:200表示请求成功
# 如何获取响应对象里面的数据
data_ = response_.text # 调用响应对象的text属性,获取到response_中的文书数据
print(type(data_))
print(data_)
# 3.解析数据(数据的提取) --> 先不用解析,以后分析
# 4.保存(分析拿到的数据是html的数据,所以保存成html文件)
with open('baidu01.html', 'w', encoding='utf-8') as f:
f.write(data_)
经检查我们发现保存的数据中汉字都变成了乱码,为什么会出现这种情况呢?
我们在调用响应对象的text属性时,text自动将获取到的字节数据解码成了字符串类型
优点:方便,不需要我们手动解码成字符串
缺点:如果解码方式和前端的编码方式不一样时会出现乱码
百度:Content-Type:text/html;charset=utf-8 说明编码方式是utf-8
获取解码方式:
print(response_.encoding) # ISO-8859-1
我们可以得到 text 的解码方式是:ISO-8859-1
综上:导致出现乱码出现的原因就是编码和解码的方式不一样
解决办法:
1. 直接修改response_.encoding的值
response_.encoding = 'utf-8'
# 导入发送网络请求的模块
import requests
# 添加程序入口(模块和包的部分)
if __name__ == '__main__':
# 1.确认目标的url(地址)
url_ = 'https://www.baidu.com/' # url一定要完整
# 2.发送网络请求获取响应
response_ = requests.get(url_)
print(response_) # <Response [200]>响应对象,状态码:200表示请求成功
# 修改解码方式
response_.encoding = 'utf-8'
# 如何获取响应对象里面的数据
data_ = response_.text # 调用响应对象的text属性,获取到response_中的文书数据
print(type(data_))
print(data_)
# 3.解析数据(数据的提取) --> 先不用解析,以后分析
# 4.保存(分析拿到的数据是html的数据,所以保存成html文件)
with open('baidu02.html', 'w', encoding='utf-8') as f:
f.write(data_)
2. 调用响应对象的content属性
# 导入发送网络请求的模块
import requests
# 添加程序入口(模块和包的部分)
if __name__ == '__main__':
# 1.确认目标的url(地址)
url_ = 'https://www.baidu.com/' # url一定要完整
# 2.发送网络请求获取响应
response_ = requests.get(url_)
print(response_) # <Response [200]>响应对象,状态码:200表示请求成功
# 如何获取响应对象里面的数据
data_ = response_.content # 调用响应对象的content属性,获取到response_中的文书数据
print(type(data_))
print(data_)
# 3.解析数据(数据的提取) --> 先不用解析,以后分析
# 4.保存(分析拿到的数据是html的数据,所以保存成html文件)
with open('baidu03.html', 'wb') as f:
f.write(data_)
需要注意的是:当我们保存时,因为要写入的数据类型是字节型,所以写入方式是 ‘wb’ 并且不需要规定编解码的方式
响应对象的text属性和content属性的区别:
text:字符串类型的数据,如果是html这种文本,文字数据一般用text获取
content:字节类型的数据,如果是图片,视频,音频一般用content获取
响应的其他属性:
response.text
响应体 str类型respones.content
响应体 bytes类型response.status_code
响应状态码response.request.headers
响应对应的请求头response.headers
响应头response.request._cookies
响应对应请求的cookieresponse.cookies
响应的cookie(经过了set-cookie动作)
五、用户代理:User-Agent
并不是所用的数据都值得被保护,所以有些网站没有反爬
并不是所有拿到的数据都是真的
打开本地html文件的三种方法:
1. pycharm进入html文件,右上角点击浏览器打开
2. pycharm,html文件右键 open in ...... 打开
3. 终端,在当前目录下,输入:start xxx.html
第一种和第二种没有区别,第三种打开方式最接近真实
没有正常用户代理User-Agent的情况
# 导入发送网络请求的模块
import requests
# 添加程序入口(模块和包的部分)
if __name__ == '__main__':
# 1.确认目标的url(地址)
url_ = 'https://www.baidu.com/' # url一定要完整
# 2.发送网络请求获取响应
response_ = requests.get(url_)
print(response_) # <Response [200]>响应对象,状态码:200表示请求成功
# 如何获取响应对象里面的数据
data_ = response_.content # 调用响应对象的content属性,获取到response_中的文书数据
print(type(data_))
print(data_)
# 3.解析数据(数据的提取) --> 先不用解析,以后分析
# 4.保存(分析拿到的数据是html的数据,所以保存成html文件)
with open('baidu04.html', 'wb') as f:
f.write(data_)
与真实百度首页对比,我们可以清楚发现获取的数据少了。
使用正常用户代理User-Agent的情况
# 导入发送网络请求的模块
import requests
# 添加程序入口(模块和包的部分)
if __name__ == '__main__':
# 1.确认目标的url(地址)
url_ = 'https://www.baidu.com/' # url一定要完整
# 在发送网络请求之前,去模拟正常的用户,使用正常的用户代理User-Agent
# User-Agent,前后不能有空格
headers_ = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Mobile Safari/537.36'
}
# 2.发送网络请求获取响应,以参数的形式携带用户代理信息,参数名为headers
response_ = requests.get(url_, headers=headers_)
print(response_) # <Response [200]>响应对象,状态码:200表示请求成功
# 如何获取响应对象里面的数据
data_ = response_.content # 调用响应对象的content属性,获取到response_中的文书数据
print(type(data_))
print(data_)
# 3.解析数据(数据的提取) --> 先不用解析,以后分析
# 4.保存(分析拿到的数据是html的数据,所以保存成html文件)
with open('baidu05.html', 'wb') as f:
f.write(data_)
与没有使用用户代理获取的数据对比,明显数据变多了