1 爬虫介绍
# http协议---》应用层协议---》主流软件(web,app,小程序)--->基本都是走http
# 爬取:网站pc端,app,小程序 的数据
# 爬虫的本质---》网络蜘蛛
# 模拟发送http请求(python模块)----》服务端返回数据----》数据清洗(模块)----》入库(mysql,文件,redis,mongodb,es)
# 可见即可爬
# 反爬
# 发送请求(验证码、频率、登录之后才可访问)
# 数据清洗(拿回来的数据需要反解)
# 法律允许的范围---》游走在边缘
# 爬虫协议:网站规定了什么让爬,什么不让怕
https://www.cnblogs.com/robots.txt
# 如果不违反,必须遵循这个协议
# 百度谷歌就是大爬虫----》一刻不停的在互联网爬页面---》存到百度自己库中----》搜索关键字---》百度库中搜---》返回结果---》点击跳到了真正的网站
# 伪静态
# 政府部门
# 爬好大夫数据医生开药数据----》分析--》药厂对接--》推销药品
# 爬虫并不是只有python可以做,任何语言都可以做
# python做爬虫好处:简单,异步爬虫框架scrapy
2 requests模块发送get请求
# 浏览器,postman可以发送http请求,pyhton也可以
# requests模块---》不仅仅用来做爬虫--》跟第三方服务通信---》非常主流的第三方库
# python内置模块 urllib模块就可以发送http请求,但是这个模块用起来复杂,有人基于urllib封装----》requests模块
# 第三方库:安装---》pip3 install requests
# 1 发送get请求获取数据
# import requests
# res=requests.get('https://www.cnblogs.com/')
# print(res.text) # 响应数据转为字符串(本来是bytes)
# with open('cnblogs.html','w') as f:
# f.write(res.text)
3 requests请求带参数
# 2 get请求中带参数
import requests
# 方式一:直接拼
# res=requests.get('https://zzk.cnblogs.com/s?w=python开发')
# 方式二:放在params参数中
# res=requests.get('https://zzk.cnblogs.com/s',params={'w':"python开发",'age':19})
# print(res.text)
# print(res.url)
## 3 url 编码和解码
from urllib import parse
## 编码 中文转百分号形式
# dict1 ={'wd': '百度翻译','age':19}
# url_data = parse.urlencode(dict1)
# print(url_data)
# res=parse.quote("张三")
# print(res)
# 解码
# s='%E5%BC%80%E5%8F%91'
# res=parse.unquote(s)
# print(res)
## 4 请求头中带header--->请求头由key-value组成
'''
重要的请求头:
user-agent:客户端是什么
referer:上一次访问的地址
# 反爬 首页-登录 如果是登录 你上一次的referer一定是登录页面,如果不是 那就是爬虫模拟
-Referer: https://www.lagou.com/gongsi/
-图片防盗链 :后端判断referer信息,如果不是自己的网站,直接禁止
cookie:登陆保存的信息 有这个才是登录
'''
# 模拟的不像,可能请求头中有些数据没带
# header = {
# 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'}
# res = requests.get('https://www.sogou.com/web?query=%E7%BE%8E%E5%A5%B3', headers=header)
# print(res.text)
# with open('meinv.html','w') as f:
# f.write(res.text)
# robots 爬虫协议
5 requests带cookie
## 5 请求中带cookie信息
# 如果cookie是登陆的,可以 看到登陆后的信息,如果不是登陆的,就看不到登陆后的信息
# 方式一:直接放在请求头中
# header = {
# 'cookie':'ECS_ID=8d6de49304b77f9fc64fa98daa4160d04ba603f8; ECS[visit_times]=9; UM_distinctid=17f8b9d060a7b3-0971ca9753ff86-113f645d-1aeaa0-17f8b9d060b8e6; CNZZDATA4603183=cnzz_eid%3D1514336119-1647308885-null%26ntime%3D1647308885; Hm_lvt_c29657ca36c6c88e02fed9a397826038=1647314798; CNZZDATA1260462072=442068313-1647311147-null%7C1647311147; Qs_lvt_201322=1647314798; ECS[username]=616564099%40qq.com; ECS[user_id]=61399; ECS[password]=4a5e6ce9d1aba9de9b31abdf303bbdc2; Qs_pv_201322=3697993930640207000%2C2230493819920933600; Hm_lpvt_c29657ca36c6c88e02fed9a397826038=1647314831; cto_bundle=3v7pUF9wbDElMkJ5bzloNkJ5JTJGeXNKZjBWb24ycjVVZ0V5dmZTMzEwWHl2bEN0ek1aYVJIT0wwaHJNTEhlY0psRSUyQlZpNTdCc3dpQm1pTEtrMTBWWW51V1pnbFh1RFJJRDUwbVNUT1VNRUEzMEgzbUV2OWpsRSUyRjEwNklzUWdhYTl0WHVVTDhRd1JZWlMlMkZuZlk5YWklMkJ6Vlg3JTJCdEpLV2JZRnRHWkklMkZ0V3hOOEl1alVXbTZhVXdTazNrU0RWSjk4elp2QXJTcmV4'
# }
# res=requests.get('http://www.aa7a.cn/',headers=header)
# print('616564099@qq.com' in res.text) # false
# 方式二:用cookie参数传递
# res=requests.get('http://www.aa7a.cn/',cookies={'ECS_ID':'8d6de49304b77f9fc64fa98daa4160d04ba603f8'})# 后面还有很多
# print('616564099@qq.com' in res.text) # false
6 post请求模拟登陆
### 6 request发送post请求模拟登陆
# body = {
# 'username': '616564099@qq.com',
# 'password': 'lqz12344',
# 'captcha': 'sadf',
# 'remember': '1',
# 'ref': 'http://www.aa7a.cn/',
# 'act': 'act_login',
# }
# # data 就是请求体内容
# res = requests.post('http://www.aa7a.cn/user.php',data=body)
# # 响应中会有登陆信息---》cookie--->登陆的cookie
# print(res.cookies)
#
# # 访问首页,带着认证过后的cookie,首页有我的个人信息
# res1=requests.get('http://www.aa7a.cn/',cookies=res.cookies)
# print('616564099@qq.com' in res1.text)
## 7 每次都要手动处理cookie---》自动处理cookie,只要登陆了,以后不用手动携带,自动携带
# body = {
# 'username': '616564099@qq.com',
# 'password': 'lqz1234',
# 'captcha': 'sadf',
# 'remember': '1',
# 'ref': 'http://www.aa7a.cn/',
# 'act': 'act_login',
# }
# # data 就是请求体内容
# # 得到一个session对象
# session=requests.session()
# # 以后再发请求,使用session发送,它会自动处理cookie
# res = session.post('http://www.aa7a.cn/user.php',data=body)
# # 响应中会有登陆信息---》cookie--->登陆的cookie
# print(res.cookies)
#
# # 访问首页,带着认证过后的cookie,首页有我的个人信息
# res1=session.get('http://www.aa7a.cn/')
# print('616564099@qq.com' in res1.text)
## 8 补充 post方法参数 json和data
'''
data=None, 使用的编码是urlencoded
json=None 使用的编码是 application/json
'''
# requests.post(url='xxxxxxxx',
# data={'xxx':'yyy'}) #没有指定请求头,#默认的请求头:application/x-www-form-urlencoed
#
# #如果我们自定义请求头是application/json,并且用data传值, 则服务端取不到值
# requests.post(url='',
# data={'':1,},
# headers={
# 'content-type':'application/json'
# })
#
# requests.post(url='',
# json={'':1,},
# ) #默认的请求头:application/json
7 响应Response
### 9 Response对象的属性和方法
## res对象
# respone=requests.get('https://www.cnblogs.com/')
# print(len(respone.text)) # 返回数据--》转成文本 原本是二进制 因为网络传输都是二进制
# print(len(respone.content)) # 返回数据---》二进制内容--->图片,视频
#
# print(respone.status_code) # 返回状态码 ---》200成功
# print(respone.headers) # 响应头字典
# print(respone.cookies) # 响应的cookie
# print(respone.cookies.get_dict()) # 把cookie对象转成字典 cookieJar对象
# print(respone.cookies.items()) # 获取所有cookie的value值
#
# print(respone.url) # 请求地址
# print(respone.history) # http是无状态无连接,每次都是新的请求--》如果有重定向--》里面放之前访问的地址
#
# print(respone.encoding) # 响应的编码格式
#关闭:response.close()
# response.iter_content() # 图片,视频,不要一次性存储,分片存储到本地,使用它
8 编码问题
### 10 编码问题--》有些网站不是使用utf8编码---》gbk编码---》response.encoding='gbk'
# import requests
# response=requests.get('http://www.autohome.com/news')
# response.encoding='gbk' #汽车之家网站返回的页面内容为gb2312编码的,而requests的默认编码为ISO-8859-1,如果不设置成gbk则中文乱码
# print(response.text)
9 获取二进制内容
### 11 获取二进制内容
# res=requests.get('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic%2F09%2F3a%2Fbc%2F093abce7b31f4c8ffdbf345375ff4abb.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1649909879&t=0654ccfaf735ff2591dd9f246b9afe22')
# # 图片内容,存到本地--->二进制存
# with open('致命诱惑.jpg','wb') as f:
# f.write(res.content)
# res=requests.get('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic%2F09%2F3a%2Fbc%2F093abce7b31f4c8ffdbf345375ff4abb.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1649909879&t=0654ccfaf735ff2591dd9f246b9afe22')
# # 图片内容,存到本地--->分段存
# with open('致命诱惑2.jpg','wb') as f:
# for line in res.iter_content(1024):
# f.write(line)
10 解析json
## 12 解析josn
# import requests
# response=requests.get('http://httpbin.org/get')
# # import json
# # res1=json.loads(response.text) #太麻烦
# res2=response.json() #直接获取json数据
# print(res2)
11 ssl认证
## 13 ssl认证--》有些https网站---》ca证书不是正规机构签发的---》不安全连接--》浏览器访问可以点击继续
## 代码访问---》跳过认证
# import requests
# from requests.packages import urllib3
# urllib3.disable_warnings() #关闭警告
# respone=requests.get('https://www.12306.cn',verify=False) #不验证证书,报警告,返回200
# print(respone.status_code)
## 手动携带证书
# import requests
# respone=requests.get('https://www.12306.cn',
# cert=('/path/server.crt',
# '/path/key'))
# print(respone.status_code)
12 使用代理
# 14 使用代理 ---》限制ip的访问频率---》爬虫速度太快,超过了限速---》切换一下ip地址即可
# 免费代理,收费代理(稳定)
import requests
proxies={
'http':'220.168.52.245:53548',#带用户名密码的代理,@符号前是用户名与密码
}
respone=requests.get('https://www.12306.cn',
proxies=proxies)
print(respone.status_code)
## 小作业---》网上有很多免费代理---》不稳定---》第三方开源的免费代理池代码--》python flask写的--》
# 源代码拉下来---》本地跑---》生成很多代理
# 代理池
# https://github.com/jhao104/proxy_pool