python——网络爬虫快速入门【reuqests篇】
2.3 pip的使用和虚拟环境的介绍
pip 是一个现代的,通用的 Python 包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能。
官方提供的pip 示例
$ pip install requests
pip 换源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
虚拟环境
在开发过程中,当需要使用python的某些工具包/框架时需要联网安装,如果在一台电脑上,想开发多个不同的项目, 需要用到同一个包的不同版本, 如果使用上面的命令, 在同一个目录下安装或者更新, 新版本会覆盖以前的版本, 其它的项目就无法运行了。
所以为了环境之间的库相互不影响,标准库不受到污染,一般开发过程中,我们会引入虚拟环境。虚拟环境可以搭建独立的Python运行环境,使得单个项目的运行环境与其他项目互不影响。
1.如何搭建虚拟环境?
安装虚拟环境及管理工具
pip install virtualenvpip install virtualenvwrapper # linux pip install virtualenvwrapper-win #Windows使用该命令
linux(win跳过)
# 1、在~(家目录)下创建目录用来存放虚拟环境 mkdir .virtualenvs# 2、打开~/.bashrc文件,并添加如下: export WORKON_HOME=$HOME/.virtualenvs source /usr/local/bin/virtualenvwrapper.sh# 3、运行 source ~/.bashrc
virtualenvwrapper基本使用
创建虚拟环境 mkvirtualenv
mkvirtualenv venv (venv是虚拟环境的名称)
基本命令
workon (不加参数查看当前所有的虚拟环境,加具体的虚拟环境则切换至该环境)
- 查看虚拟环境
[root@localhost ~]# workon py2 py3
- 切换虚拟环境
[root@localhost ~]# workon py3 (py3) [root@localhost ~]#
- 退出虚拟环境
(py3) [root@localhost ~]# deactivate [root@localhost ~]#
- 删除虚拟环境
rmvirtualenv venv
2.4 reuqests库介绍
1.为什么要重点学习requests模块,而不是urllib
urllib是python中的一个标准库可以用来请求网络资源,但其工序操作比较繁杂。
requests库是urllib的一个封装库,操作简单
requests在python2 和python3中通用,方法完全一样
Requests能够自动帮助我们解压(gzip压缩的等)响应内容
2.第一个爬虫程序(案例一)
- 爬取目标: http://www.baidu.com
- 我们通过 ipython 来进行演示
pip install ipython # 安装ipython
pip install requests # 安装requests库
- 启动 ipython ,通过命令行进入虚拟环境,安装好ipython和requests库后,输入ipython进入ipython环境
In [1]: import requestsIn [2]: requests.get("http://www.baidu.com")
Out[2]: <Response [200]>In [3]: response = requests.get("http://www.baidu.com")
In [4]: response.text
Out[4]: '<!DOCTYPE html>\r\n<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>ç\x99¾åº¦ä¸\x80ä¸\x8bï¼\x8cä½\xa0å°±ç\x9f¥é\x81\x93</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=ç\x99¾åº¦ä¸\x80ä¸\x8b class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>æ\x96°é\x97»</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>å\x9c°å\x9b¾</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>è§\x86é¢\x91</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>è´´å\x90§</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>ç\x99»å½\x95</a> </noscript> <script>document.write(\'<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=\'+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ \'" name="tj_login" class="lb">ç\x99»å½\x95</a>\');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">æ\x9b´å¤\x9a产å\x93\x81</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>å\x85³äº\x8eç\x99¾åº¦</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使ç\x94¨ç\x99¾åº¦å\x89\x8då¿\x85读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>æ\x84\x8fè§\x81å\x8f\x8dé¦\x88</a> 京ICPè¯\x81030173å\x8f· <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>\r\n'
步骤:
导入requests库 import requests
发送请求并接收响应 response = rquests.get(url)
解析响应 response.txt
response的常用属性:
response.text
响应体 str类型respones.content
响应体 bytes类型response.status_code
响应状态码response.request.headers
响应对应的请求头response.headers
响应头response.request.cookies
响应对应请求的cookieresponse.cookies
响应的cookie(经过了set-cookie动作)
3. response.text 和response.content的区别
response.text
- 类型:str
- 解码类型: requests模块自动根据HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
- 如何修改编码方式:
response.encoding=”gbk”
response.content
- 类型:bytes
- 解码类型: 没有指定
- 如何修改编码方式:
response.content.decode(“utf8”)
获取网页源码的通用方式:
response.content.decode()
response.content.decode("GBK")
response.text
以上三种方法从前往后尝试,能够100%的解决所有网页解码的问题
所以:更推荐使用response.content.decode()
的方式获取响应的html页面
案例二:
爬取目标:百度的logo
演示使用:pycharm
- 查看虚拟环境是否搭载成功
- 根据需要创建目录结构以及文件
在虚拟环境中安装requests库
编写程序
首先我们要确定url
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/8/14 13:45
# @Author : GHongimport requestsurl = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" # 确定百度logo的urlresponse = requests.get(url) # 发送请求接收响应# 解析响应
img = response.content# 保存数据资源
with open("../sources/image/baidu_logo.png", "wb") as f:f.write(img)
最简单爬虫流程总结:
- 确定具体资源url
- 发起请求,接收响应
- 解析响应
- 保存数据
2.5 发送带有header的的请求
1.查看请求头和响应头
import requestsresponse = requests.get("http://www.baidu.com")# 查看请求头和响应头print("请求头:", response.request.headers)
print("=" * 35)
print("响应头:", response.headers)
请求头: {'User-Agent': 'python-requests/2.24.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
===================================
响应头: {'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Fri, 14 Aug 2020 06:05:10 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:27:57 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}
‘User-Agent’: ‘python-requests/2.24.0’ # 用户代理
‘Accept-Encoding’: ‘gzip, deflate’ # 编码信息
反扒点一:代理反爬
在前面的学习中,我们了解了robots协议,上边规定了哪些用户代理可以获取数据,哪些用户代理不能获取数据,这里的用户代理 (User-Agent) 就是一个重要的参数,很多网站都会用这个来阻止爬虫获取响应。
User-Agent 的作用就是告诉服务器,我是用什么浏览器来访问你的网站的,如果对方的服务器中布置了代码对请求的User-Agent进行监控,阻挡了一部分的爬虫程序,一些名字为Spider的爬虫就无法再访问该网站的资源,这个反爬已经被绝大部分开发者所熟知,所以很多网站都不做User-Agent拦截,以免造成真正用户的误伤。
User-Agent 伪装 (披着羊皮的狼)
案例三:
import requestsresponse = requests.get("http://www.baidu.com")print("伪装前的User-Agent:", response.request.headers["User-Agent"])headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"} # 告诉百度的服务器,我是谷歌浏览器response = requests.get("http://www.baidu.com", headers=headers)
print("伪装后的User-Agent:", response.request.headers["User-Agent"])
伪装前的User-Agent: python-requests/2.24.0
伪装后的User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36
总结:
header的形式:字典
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
用法
requests.get(url, headers=headers)
通过浏览器检查代开控制台,在抓包出可以看到浏览器的User-Agent,再此处复制过来用即可
总结:通过headers参数来做伪装欺骗服务器
- headers 的值是一个字典,其内部的属性是一个个的键值对
- 通过headers参数可以将我们的headers传递给请求,披上羊皮就是羊了
2.6 发送带参数的请求
1.参数介绍
我们在使用百度搜索的时候经常发现url地址中会有一个 ?
,那么该问号后边的就是请求参数,又叫做查询字符串
[https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=reques%E5%BA%93&oq=python%25E8%2599%259A%25E6%258B%259F%25E7%258E%25AF%25E5%25A2%2583&rsv_pq=dfa9a62100001b21&rsv_t=fa2cqIfxcw0879rrylW9bU0QPR2n1QC1yabVcT66zoeiKvucSugwbmeyJAw&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=11&rsv_sug1=14&rsv_sug7=100&rsv_sug2=0&rsv_btype=t&inputT=8345&rsv_sug4=8344]
什么叫做请求参数:
例1: http://www.webkaka.com/tutorial/server/2015/021013/
例2:https://www.baidu.com/s?wd=python&a=c
例1中没有请求参数!例2中?后边的就是请求参数
请求参数的形式:字典
kw = {'wd':'长城'}
请求参数的用法
requests.get(url,params=kw)
关于参数的注意点
在url地址中, 很多参数是没有用的,比如百度搜索的url地址,其中参数只有一个字段有用,其他的都可以删除 如何确定那些请求参数有用或者没用:挨个尝试! 对应的,在后续的爬虫中,越到很多参数的url地址,都可以尝试删除参数
没有用的参数尽可能的删除,只要不影响数据的爬取一律删除,保持代码的整洁性,如果所有的参数都是必要的,或者必要参数过多就用字典生成式进行参数字典生成
案例四
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/8/14 14:34
# @Author : GHongimport requestsurl = "https://www.baidu.com/s?" # 确定url为百度# 构建查询参数,通过观察发现其搜索的参数为wdwd = input("请输入你要查询的信息:")
params = {}
params["wd"] = wdheaders = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"} # 告诉百度的服务器,我是谷歌浏览器response = requests.get(url, params=params, headers=headers)# print(response.content.decode())with open("../sources/file/baidu=%s.html" % wd, "w", encoding="utf8") as f:f.write(response.content.decode())
- 这个案例中我们首先通过真实的浏览器进行观察发现只有wd是百度搜索的必要关键字
- 随后我们进行了数据尝试爬取,发现百度并没有给我们返回我们想要的数据
- 然后我们加入User-Agent 伪装,然后再次尝试数据爬取
- 这一次百度服务器返回了我们需要的数据,数据抓取成功
- 进行数据保存,为.html文件,打开验证
练习1
- 爬取新浪的首页,以Html的形式保存 【难度:0.5星】
- 爬取百度贴吧,要求实现可以爬取任何贴吧,的任何页数的全部内容【难度 1星】
练习参考答案 提取码:htgy
阶段小结
- requests模块的介绍:能够帮助我们发起请求获取响应
- requests的基本使用:
requests.get(url)
- 以及response常见的属性:
response.text
响应体 str类型respones.content
响应体 bytes类型response.status_code
响应状态码response.request.headers
响应对应的请求头response.headers
响应头response.request._cookies
响应对应请求的cookieresponse.cookies
响应的cookie(经过了set-cookie动作)
- 掌握 requests.text和content的区别:text返回str类型,content返回bytes类型
- 掌握 解决网页的解码问题:
response.content.decode()
response.content.decode("GBK")
response.text
- 掌握 requests模块发送带headers的请求:
requests.get(url, headers={})
- 掌握 requests模块发送带参数的get请求:
requests.get(url, params={})
2.7 reuqests的深入使用
上一阶段我们学习了如何使用requests发送get请求
如何进行用户代理伪装
以及如何设置查询参数
还有响应的集中类型
响应的状态码等
这一节,我们讲解如何使用requests库来发送POST请求,如何爬取需要登录等网站等
- 能够应用requests发送post请求的方法
- 能够应用requests模块使用代理的方法
- 了解代理ip的分类
1.使用requests发送POST请求
思考:哪些地方我们会用到POST请求?
- 登录注册( POST 比 GET 更安全)
- 需要传输大文本内容的时候( POST 请求对数据长度没有要求)
1.1 requests发送post请求语法:
用法:
response = requests.post("http://www.baidu.com/", \data = data,headers=headers)
data 的形式:字典
案例五=>百度翻译
第一步找到相关链接:通过浏览器抓包找到目标url
第二步分析数据表单
第三步尝试进行爬取
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/8/14 17:44
# @Author : GHongimport requests# 确定目标urlurl = "https://fanyi.baidu.com/v2transapi?from=zh&to=en"
data = {"from": "zh","to": "en","query": "中文","transtype": "translang","simple_means_flag": 3,"sign": 567986.805251,"token": "038a703da60aa023b520a62e56c3daac","domain": "common"
}headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36",
"cookie": "BIDUPSID=67C436ADF5878B8C8473920E4991735D; PSTM=1583145438; BAIDUID=67C436ADF5878B8CD8FC329F6003854F:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; H_WISE_SIDS=139914_144981_142018_144884_141877_141748_145498_144134_145271_144470_144483_131246_144682_137749_144742_138883_140259_141941_127969_140066_144791_140595_142420_143491_143923_144484_131424_100805_142206_145522_145351_107316_145611_139910_144568_144306_143477_144966_142427_142911_140312_145424_143549_144160_142507_144017_145399_143854_110085; MCITY=-257%3A; BDUSS=TdXNXR2WXl2eEl1a0FxekhhZmJCZmxhVkh-b1J1T3B2d3pDNVJlbmxDdHpJVlpmSVFBQUFBJCQAAAAAAAAAAAEAAACOkPqdvPu57bXEyMtiYrWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHOULl9zlC5fR; BDUSS_BFESS=TdXNXR2WXl2eEl1a0FxekhhZmJCZmxhVkh-b1J1T3B2d3pDNVJlbmxDdHpJVlpmSVFBQUFBJCQAAAAAAAAAAAEAAACOkPqdvPu57bXEyMtiYrWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHOULl9zlC5fR; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=6; H_PS_PSSID=1437_32539_32327_31253_32046_32399_32407_32115_32505_32481_22158; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1597395475; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1597397619; __yjsv5_shitong=1.0_7_821f0d690902ea5bc7f01368695d4f62d31b_300_1597397618595_113.65.230.142_172b5b7b; yjs_js_security_passport=753c00e4926b4060ccd3c73a3d2d96a0f9fab9b8_1597397620_js"
}response = requests.post(url, data=data, headers=headers)
print(response.content.decode())
爬取过程分析:
- 抓包确定url
- 将表单数据构建好,发起请求,发现返回数据不是我们预期的。
- 于是我们第二次加上user-Agent进行伪装,依旧没有返回预期数据
- 第三次我们加入Cookie信息,这次成功获取到了数据
返回数据是个JSON类型,这里我们可以通过
网站进行JSON数据结构分析:传送门
通过对返回结果的数据结构分析,结果如下
- 我们发现我们想要的数据在data下边的dst中
- 这时候我们可以通过JSON这个python内置的标准库进行数据的提取
from json import loads # 通过JSON包中导入loads模块
import requests
from json import loads# 确定目标urlurl = "https://fanyi.baidu.com/v2transapi?from=zh&to=en"
data = {"from": "zh","to": "en","query": "中文","transtype": "translang","simple_means_flag": 3,"sign": 567986.805251,"token": "038a703da60aa023b520a62e56c3daac","domain": "common"
}headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36","cookie": "BIDUPSID=67C436ADF5878B8C8473920E4991735D; PSTM=1583145438; BAIDUID=67C436ADF5878B8CD8FC329F6003854F:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; H_WISE_SIDS=139914_144981_142018_144884_141877_141748_145498_144134_145271_144470_144483_131246_144682_137749_144742_138883_140259_141941_127969_140066_144791_140595_142420_143491_143923_144484_131424_100805_142206_145522_145351_107316_145611_139910_144568_144306_143477_144966_142427_142911_140312_145424_143549_144160_142507_144017_145399_143854_110085; MCITY=-257%3A; BDUSS=TdXNXR2WXl2eEl1a0FxekhhZmJCZmxhVkh-b1J1T3B2d3pDNVJlbmxDdHpJVlpmSVFBQUFBJCQAAAAAAAAAAAEAAACOkPqdvPu57bXEyMtiYrWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHOULl9zlC5fR; BDUSS_BFESS=TdXNXR2WXl2eEl1a0FxekhhZmJCZmxhVkh-b1J1T3B2d3pDNVJlbmxDdHpJVlpmSVFBQUFBJCQAAAAAAAAAAAEAAACOkPqdvPu57bXEyMtiYrWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHOULl9zlC5fR; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=6; H_PS_PSSID=1437_32539_32327_31253_32046_32399_32407_32115_32505_32481_22158; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1597395475; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1597397619; __yjsv5_shitong=1.0_7_821f0d690902ea5bc7f01368695d4f62d31b_300_1597397618595_113.65.230.142_172b5b7b; yjs_js_security_passport=753c00e4926b4060ccd3c73a3d2d96a0f9fab9b8_1597397620_js"
}response = requests.post(url, data=data, headers=headers)json_data = response.content.decode()dict_data = loads(json_data) # 通过dumps将JSON转换为字典# print(dict_data["data"]["dst"]) # KeyError: 'data' 第一次尝试他说没有data这个键# print(dict_data) # 通过观察解析的字典我们发现外边套多了一层 'trans_result'# print(dict_data["trans_result"]["data"]) # 我们发现这一层是一个列表,取0号位索引print(dict_data["trans_result"]["data"][0]["dst"]) # 终于拿到了我们想要的结果
爬取案例解析:
- 首先我们要确定真正的URL是哪一个
- 然后开始第一次爬取尝试,构建POST请求表单数据,第一次被反爬
- 加上User-Agent 再次尝试爬取,第二次被反爬
- 加上cookie 成功爬取到相关信息,返回数据格式为JSON
- 在JSON包中导入loads模块进行数据转化,JSON ==> dict 字典
- 分析返回结果JSON的数据结构,经过层层剖析我们发下,最外层是一个字典,通过键 trans_result 获取值
- 第二层是一个字典,通过data关键字取出我们需要的值
- 第三层是一个列表,通过0号位索引取出值
- 第四层就是我们的目标值,到此为止解析完成
- 把表单query关键字改成动态参数传输,一个通过爬虫调用百度翻译的中译英翻译接口**【拿来即用,爬虫有风险使用需谨慎】**
练习2
- 人人网登录爬取练习【难度1星】
- 学校课表爬取,自己爬取自己的课表【华软,难度:3.5 星】
参考答案 提取码:0a0j
小结:
网站的url并不一定是我们的真正的目标url
POST请求表单数据传输通过data参数
简单反反爬技术:
第一步:User-Agent伪装
第二步:找Cookie
第三步:找Referrer
第四步:考虑是否存在JS加密
爬虫流程:
- 确定url
- 获取数据
- 数据解析
- 数据入库
2. 代理的使用
2.1 为什么要使用代理
让服务器以为不是同一个客户端在请求
防止我们的真实地址被泄露,防止被追究 (你懂的)
2.2 理解正向代理和反向代理的区别
通过上图可以看出:
正向代理:对于浏览器知道服务器的真实地址
反向代理:浏览器不知道服务器的真实地址
(正向代理) ==》 替身术 ,代替我去发请求
(反向代理) ==》 多重影分身之术,你访问的任何一个都会把经验数据带回给我本体(服务器)
2.4 代理使用
用法:
requests.get("http://www.baidu.com", proxies = proxies)
proxies的形式:字典
例如:
proxies = { "http": "http://12.34.56.79:9527", "https": "https://12.34.56.79:9527", }
案例六 ==> ip查询网址 http://httpbin.org/ip 或 http://mip.chinaz.com/
import requests# http://httpbin.org/ip
response = requests.get("http://mip.chinaz.com/", proxies={"http": "http://165.225.34.56:10605"})
print(response.content.decode())
2.5 代理IP的分类
根据代理ip的匿名程度,代理IP可以分为下面四类:
- 透明代理(Transparent Proxy):透明代理虽然可以直接“隐藏”你的IP地址,但是还是可以查到你是谁。
- 匿名代理(Anonymous Proxy):使用匿名代理,别人只能知道你用了代理,无法知道你是谁。
- 高匿代理(Elite proxy或High Anonymity Proxy):高匿代理让别人根本无法发现你是在用代理,所以是最好的选择。
在使用的使用,毫无疑问使用高匿代理效果最好
从请求使用的协议可以分为:
- http代理
- https代理
- socket代理等
不同分类的代理,在使用的时候需要根据抓取网站的协议来选择
2.6 代理IP使用的注意点
反反爬
使用代理ip是非常必要的一种
反反爬
的方式但是即使使用了代理ip,对方服务器任然会有很多的方式来检测我们是否是一个爬虫,比如:
一段时间内,检测IP访问的频率,访问太多频繁会屏蔽 【可以使用大量的代理来进行欺骗】
检查Cookie,User-Agent,Referer等header参数,若没有则屏蔽 【基本反反爬参数】
服务方购买所有代理提供商,加入到反爬虫数据库里,若检测是代理则屏蔽 【最狗的,两头赚钱】
所以更好的方式在使用代理ip的时候使用随机的方式进行选择使用,不要每次都用一个代理ip
代理ip池的更新
购买的代理ip很多时候大部分(超过60%)可能都没办法使用,这个时候就需要通过程序去检测哪些可用,把不能用的删除掉。
好用的高匿代理都是花钱买的,不过网上也有很多免费的代理可以供我们使用,我们可以通过爬虫来爬取这些代理来组建代理池,并定期进行测试,优胜略汰的原则保证代理池中代理的质量。
3. reuqests处理cookie
1 爬虫中使用cookie
为了能够通过爬虫获取到登录后的页面,或者是解决通过cookie的反扒,需要使用request来处理cookie相关的请求
1.1 爬虫中使用cookie的利弊
- 带上cookie的好处
- 能够访问登录后的页面
- 能够实现部分反反爬
- 带上cookie的坏处
- 一套cookie往往对应的是一个用户的信息,请求太频繁有更大的可能性被对方识别为爬虫
- 那么上面的问题如何解决 ?使用多个账号
1.2 requests处理cookie的方法
使用requests处理cookie有三种方法:
- cookie字符串放在headers中
- 把cookie字典放传给请求方法的cookies参数接收
- 使用requests提供的session模块
2 cookie添加在headers中
2.1 headers中cookie的位置
headers中的cookie:[拆分小技巧:字典生成式]
- 使用分号(;)隔开
- 分号两边的类似a=b形式的表示一条cookie
- a=b中,a表示键(name),b表示值(value)
- 在headers中仅仅使用了cookie的name和value
2.2 cookie的具体组成的字段
由于headers中对cookie仅仅使用它的name和value,所以在代码中我们仅仅需要cookie的name和value即可
2.3 在headers中使用cookie
复制浏览器中的cookie到代码中使用,之前的案例中有演示过该用法
headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
"Cookie":" Pycharm-26c2d973=dbb9b300-2483-478f-9f5a-16ca4580177e; Hm_lvt_98b9d8c2fd6608d564bf2ac2ae642948=1512607763; Pycharm-26c2d974=f645329f-338e-486c-82c2-29e2a0205c74; _xsrf=2|d1a3d8ea|c5b07851cbce048bd5453846445de19d|1522379036"}requests.get(url,headers=headers)
注意:
cookie有过期时间 ,所以直接复制浏览器中的cookie可能意味着下一程序继续运行的时候需要替换代码中的cookie,对应的我们也可以通过一个程序专门来获取cookie供其他程序使用;当然也有很多网站的cookie过期时间很长,这种情况下,直接复制cookie来使用更加简单
3 使用cookies参数接收字典形式的cookie
- cookies的形式:字典
cookies = {"cookie的name":"cookie的value"}
- 使用方法:
requests.get(url,headers=headers,cookies=cookie_dict}
4 使用requests.session处理cookie
前面使用手动的方式使用cookie,那么有没有更好的方法在requets中处理cookie呢?
requests 提供了一个叫做session类,来实现客户端和服务端的会话保持
会话保持有两个内涵:
- 保存cookie,下一次请求会带上前一次的cookie
- 实现和服务端的长连接,加快请求速度
4.1 使用方法
session = requests.session()
response = session.get(url,headers)
session实例在请求了一个网站后,对方服务器设置在本地的cookie会保存在session中,下一次再使用session请求对方服务器的时候,会带上前一次的cookie
5 小结
- cookie字符串可以放在headers字典中,键为Cookie,值为cookie字符串
- 可以把cookie字符串转化为字典,使用请求方法的cookies参数接收
- 使用requests提供的session模块,能够自动实现cookie的处理,包括请求的时候携带cookie,获取响应的时候保存cookie
练习3 爬取IP代理,组建代理池 url 自选 (3.5星)(百度ip代理,一抓一大把)
代理高匿测试:http://httpbin.org/ip 或 http://mip.chinaz.com/
参考答案爬取ip代理 提取码:9ghy
2.8 requests模块的其他方法
- 掌握requests中cookirJar的处理方法
- 掌握requests解决https证书错误的问题
- 掌握requests中超时参数的使用
- 掌握retrying模块的使用
1 requests中cookirJar的处理方法
使用request获取的resposne对象,具有cookies属性,能够获取对方服务器设置在本地的cookie,但是如何使用这些cookie呢?
1.1 方法介绍
- response.cookies是CookieJar类型
- 使用requests.utils.dict_from_cookiejar,能够实现把cookiejar对象转化为字典
1.2 方法展示
import requestsurl = "http://www.baidu.com"
#发送请求,获取resposne
response = requests.get(url)
print(type(response.cookies))#使用方法从cookiejar中提取数据
cookies = requests.utils.dict_from_cookiejar(response.cookies)
print(cookies)
输出为:
<class 'requests.cookies.RequestsCookieJar'>
{'BDORZ': '27315'}
注意:
在前面的requests的session类中,我们不需要处理cookie的任何细节,如果有需要,我们可以使用上述方法来解决
2 requests处理证书错误
经常我们在网上冲浪时,经常能够看到下面的提示:
出现这个问题的原因是:ssl的证书不安全导致
2.1 代码中发起请求的效果
那么如果在代码中请求会怎么样呢?
import requestsurl = "https://www.12306.cn/mormhweb/" # 目前最新测试已修复
response = requests.get(url)
返回证书错误,如下:
ssl.CertificateError ...
2.2 解决方案
为了在代码中能够正常的请求,我们修改添加一个参数
import requestsurl = "https://www.12306.cn/mormhweb/"
response = requests.get(url,verify=False)
3 超时参数的使用
在平时网上冲浪的过程中,我们经常会遇到网络波动,这个时候,一个请求等了很久可能任然没有结果
在爬虫中,一个请求很久没有结果,就会让整个项目的效率变得非常低,这个时候我们就需要对请求进行强制要求,让他必须在特定的时间内返回结果,否则就报错
3.1 超时参数使用方法如下:
response = requests.get(url,timeout=3)
通过添加timeout参数,能够保证在3秒钟内返回响应,否则会报错
注意:
这个方法还能够拿来检测代理ip的质量,如果一个代理ip在很长时间没有响应,那么添加超时之后也会报错,对应的这个ip就可以从代理ip池中删除
4 retrying模块的使用
使用超时参数能够加快我们整体的请求速度,但是在正常的网页浏览过成功,如果发生速度很慢的情况,我们会做的选择是刷新页面,那么在代码中,我们是否也可以刷新请求呢?
对应的,retrying模块就可以帮助我们解决
4.1 retrying模块的使用
pip install retrying
retrying模块的地址:https://pypi.org/project/retrying/
retrying 模块的使用
- 使用retrying模块提供的retry模块
- 通过装饰器的方式使用,让被装饰的函数反复执行
- retry中可以传入参数
stop_max_attempt_number
,让函数报错后继续重新执行,达到最大执行次数的上限,如果每次都报错,整个函数报错,如果中间有一个成功,程序继续往后执行
4.2 retrying和requests的简单封装
实现一个发送请求的函数,每次爬虫中直接调用该函数即可实现发送请求,在其中
- 使用timeout实现超时报错(一般使用这个就够了)
- 使用retrying模块实现重试
代码参考:
# parse.py
import requests
from retrying import retryheaders = {}#最大重试3次,3次全部报错,才会报错
@retry(stop_max_attempt_number=3)
def _parse_url(url)#超时的时候回报错并重试response = requests.get(url, headers=headers, timeout=3) #状态码不是200,也会报错并重试assert response.status_code == 200return responsedef parse_url(url)try: #进行异常捕获response = _parse_url(url)except Exception as e:print(e)#报错返回Noneresponse = Nonereturn response
练习4 网易新闻|新冠疫情数据(3.5星)
https://wp.m.163.com/163/page/news/virus_report/index.html?_nw_=1&_anw_=1
参考答案 提取码:i7z1
python——网络爬虫快速入门【reuqests篇】相关推荐
- Python3网络爬虫快速入门实战解析(一小时入门 Python 3 网络爬虫)
Python3网络爬虫快速入门实战解析(一小时入门 Python 3 网络爬虫) https://blog.csdn.net/u012662731/article/details/78537432 出 ...
- Python教程:网络爬虫快速入门实战解析
建议: 请在电脑的陪同下,阅读本文.本文以实战为主,阅读过程如稍有不适,还望多加练习. 网络爬虫简介 网络爬虫,也叫网络蜘蛛(Web Spider).它根据网页地址(URL)爬取网页内容,而网页地址( ...
- python3 爬虫实例_【实战练习】Python3网络爬虫快速入门实战解析(上)
原标题:[实战练习]Python3网络爬虫快速入门实战解析(上) 摘要 使用python3学习网络爬虫,快速入门静态网站爬取和动态网站爬取 [ 前言 ] 强烈建议:请在电脑的陪同下,阅读本文.本文以实 ...
- 【读书笔记】Python网络爬虫从入门到实践(第2版)-唐松,爬虫基础体系巩固和常见场景练习
[概述] 书名:Python网络爬虫从入门到实践(第2版) 作者:唐松 日期:2021年08月01日 读书用时:1568页,100小时,59个笔记 [读书笔记] ◆ 1.2 网络爬虫是否合法 爬虫协议 ...
- Python3网络爬虫快速入门实战解析
Python3网络爬虫快速入门实战解析 标签: python网络爬虫 2017-09-28 14:48 6266人阅读 评论(34) 收藏 举报 分类: Python(26) 作者同类文章X 版权声明 ...
- Python3 网络爬虫快速入门实战解析
点击上方"Python高校",关注 文末干货立马到手 作者:Jack Cui http://cuijiahua.com/blog/2017/10/spider_tutorial_1 ...
- beautifulsoup网页爬虫解析_Python3 网络爬虫快速入门实战解析
点击上方"Python高校",关注 文末干货立马到手 作者:Jack Cui http://cuijiahua.com/blog/2017/10/spider_tutorial_1 ...
- python编程入门到实践 百度云-python网络爬虫从入门到实践pdf
python网络爬虫从入门到实践pdf是一本非常热门的编程教学.这本书籍详细讲解了Python以及网络爬虫相关知识,非常适合新手阅读,需要的用户自行下载吧. Python网络爬虫从入门到实践电子书介绍 ...
- python网络爬虫教程-终于明了python网络爬虫从入门到实践
Python是一款功能强大的脚本语言,具有丰富和强大的库,重要的是,它还具有很强的可读性,易用易学,非常适合编程初学者入门.以下是小编为你整理的python网络爬虫从入门到实践 环境配置:下载Pyth ...
最新文章
- 听客来团队scrum敏捷开发工具实践分享
- H5 中的 new FileReader() 以及 识别上传的文件是否为图片
- 作家百态之二:山南海北
- Android学习笔记---HttpClient入门,使用方法,及简介
- Stanford机器学习---第十一讲.异常检测
- 基于SOLIDWORKS Simulation的有限元分析法实例应用
- 2.7 汽车之家口碑爬虫
- 腐蚀rust电脑分辨率调多少_腐蚀Rust帧数优化指南 游戏FPS提高方法说明
- java学习第114天,p699-706(05/12),完成QQ群发
- 舵机弹跳机器人_Nature:蚂蚁机器人弹跳力惊人 还会分工合作
- 犹太人的智慧书《塔木德》(Talmud)
- 数学分析(1): 实数
- Python读取图像数据的常用方法
- Android 获取彩信文本内容及 发送时间 发送人
- Spring的ioc控制反转
- python数据处理与分析(汇总)
- 数据挖掘的概念和步骤
- 一个实验了解多层内网渗透
- 关闭Windows XP系统Beep提示音
- 生物信息学技术在罕见病研究中的应用
热门文章
- linux内核wifi驱动,基于2.6.35内核的SDIO-WiFi驱动移植
- php.ini 中register_globals的ON和Off配置
- skype模糊搜索联系人_我越来越在挖掘Skype,我已经厌倦了所有不同的“我”问题。 另外,移动您的Skype联系人。...
- 准工业级代码分享:Python用于自动生成EXCEL周期报告
- vitepress添加脚注插件
- 两万文字详解Pandas DataFrame(持续更新)
- c#和java部署pytorch同事识别两个图片_人脸识别漏洞频出?这里有个开源静默活体检测算法,超低运算量、工业级可用...
- C语言源代码系列-管理系统之职工工资管理系统
- 扁鹊三兄弟——电脑永远无法取代的正确判断
- HTML背景图全屏显示