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.如何搭建虚拟环境?

  1. 安装虚拟环境及管理工具

    pip install virtualenvpip install virtualenvwrapper   # linux
    pip install virtualenvwrapper-win  #Windows使用该命令
    
  2. linux(win跳过)

    # 1、在~(家目录)下创建目录用来存放虚拟环境
    mkdir .virtualenvs# 2、打开~/.bashrc文件,并添加如下:
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh# 3、运行
    source ~/.bashrc
    
  3. virtualenvwrapper基本使用

    1. 创建虚拟环境 mkvirtualenv

      mkvirtualenv venv  (venv是虚拟环境的名称)
      
    2. 基本命令

    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库
  1. 启动 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&amp;tpl=mn&amp;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>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使ç\x94¨ç\x99¾åº¦å\x89\x8då¿\x85读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>æ\x84\x8fè§\x81å\x8f\x8dé¦\x88</a>&nbsp;京ICPè¯\x81030173å\x8f·&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>\r\n'

步骤:

  1. 导入requests库 import requests

  2. 发送请求并接收响应 response = rquests.get(url)

  3. 解析响应 response.txt

response的常用属性:
  • response.text 响应体 str类型
  • respones.content 响应体 bytes类型
  • response.status_code 响应状态码
  • response.request.headers 响应对应的请求头
  • response.headers 响应头
  • response.request.cookies 响应对应请求的cookie
  • response.cookies 响应的cookie(经过了set-cookie动作)

3. response.text 和response.content的区别

  • response.text

    • 类型:str
    • 解码类型: requests模块自动根据HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
    • 如何修改编码方式:response.encoding=”gbk”
  • response.content
    • 类型:bytes
    • 解码类型: 没有指定
    • 如何修改编码方式:response.content.decode(“utf8”)

获取网页源码的通用方式:

  1. response.content.decode()
  2. response.content.decode("GBK")
  3. response.text

以上三种方法从前往后尝试,能够100%的解决所有网页解码的问题

所以:更推荐使用response.content.decode()的方式获取响应的html页面

案例二:

爬取目标:百度的logo

演示使用:pycharm

  • 查看虚拟环境是否搭载成功

  1. 根据需要创建目录结构以及文件

  1. 在虚拟环境中安装requests库

  2. 编写程序

  3. 首先我们要确定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)

最简单爬虫流程总结:

  1. 确定具体资源url
  2. 发起请求,接收响应
  3. 解析响应
  4. 保存数据

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参数来做伪装欺骗服务器

  1. headers 的值是一个字典,其内部的属性是一个个的键值对
  2. 通过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

  1. 爬取新浪的首页,以Html的形式保存 【难度:0.5星】
  2. 爬取百度贴吧,要求实现可以爬取任何贴吧,的任何页数的全部内容【难度 1星】

练习参考答案 提取码:htgy

阶段小结

  1. requests模块的介绍:能够帮助我们发起请求获取响应
  2. requests的基本使用:requests.get(url)
  3. 以及response常见的属性:
    • response.text 响应体 str类型
    • respones.content 响应体 bytes类型
    • response.status_code 响应状态码
    • response.request.headers 响应对应的请求头
    • response.headers 响应头
    • response.request._cookies 响应对应请求的cookie
    • response.cookies 响应的cookie(经过了set-cookie动作)
  4. 掌握 requests.text和content的区别:text返回str类型,content返回bytes类型
  5. 掌握 解决网页的解码问题:
    • response.content.decode()
    • response.content.decode("GBK")
    • response.text
  6. 掌握 requests模块发送带headers的请求:requests.get(url, headers={})
  7. 掌握 requests模块发送带参数的get请求:requests.get(url, params={})

2.7 reuqests的深入使用

  • 上一阶段我们学习了如何使用requests发送get请求

  • 如何进行用户代理伪装

  • 以及如何设置查询参数

  • 还有响应的集中类型

  • 响应的状态码等


    这一节,我们讲解如何使用requests库来发送POST请求,如何爬取需要登录等网站等

    1. 能够应用requests发送post请求的方法
    2. 能够应用requests模块使用代理的方法
    3. 了解代理ip的分类

1.使用requests发送POST请求

思考:哪些地方我们会用到POST请求?

  1. 登录注册( POST 比 GET 更安全)
  2. 需要传输大文本内容的时候( 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())

爬取过程分析:

  1. 抓包确定url
  2. 将表单数据构建好,发起请求,发现返回数据不是我们预期的。
  3. 于是我们第二次加上user-Agent进行伪装,依旧没有返回预期数据
  4. 第三次我们加入Cookie信息,这次成功获取到了数据

返回数据是个JSON类型,这里我们可以通过

网站进行JSON数据结构分析:传送门

通过对返回结果的数据结构分析,结果如下

  • 我们发现我们想要的数据在data下边的dst中
  • 这时候我们可以通过JSON这个python内置的标准库进行数据的提取
  1. 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"])  # 终于拿到了我们想要的结果

爬取案例解析:

  1. 首先我们要确定真正的URL是哪一个
  2. 然后开始第一次爬取尝试,构建POST请求表单数据,第一次被反爬
  3. 加上User-Agent 再次尝试爬取,第二次被反爬
  4. 加上cookie 成功爬取到相关信息,返回数据格式为JSON
  5. 在JSON包中导入loads模块进行数据转化,JSON ==> dict 字典
  6. 分析返回结果JSON的数据结构,经过层层剖析我们发下,最外层是一个字典,通过键 trans_result 获取值
  7. 第二层是一个字典,通过data关键字取出我们需要的值
  8. 第三层是一个列表,通过0号位索引取出值
  9. 第四层就是我们的目标值,到此为止解析完成
  10. 把表单query关键字改成动态参数传输,一个通过爬虫调用百度翻译的中译英翻译接口**【拿来即用,爬虫有风险使用需谨慎】**

练习2

  1. 人人网登录爬取练习【难度1星】

  1. 学校课表爬取,自己爬取自己的课表【华软,难度:3.5 星】

参考答案 提取码:0a0j

小结:

  1. 网站的url并不一定是我们的真正的目标url

  2. POST请求表单数据传输通过data参数

  3. 简单反反爬技术:

    • 第一步:User-Agent伪装

    • 第二步:找Cookie

    • 第三步:找Referrer

    • 第四步:考虑是否存在JS加密

  4. 爬虫流程:

    • 确定url
    • 获取数据
    • 数据解析
    • 数据入库

2. 代理的使用

2.1 为什么要使用代理

  1. 让服务器以为不是同一个客户端在请求

  2. 防止我们的真实地址被泄露,防止被追究 (你懂的)

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的利弊
  1. 带上cookie的好处

    • 能够访问登录后的页面
    • 能够实现部分反反爬
  2. 带上cookie的坏处
    • 一套cookie往往对应的是一个用户的信息,请求太频繁有更大的可能性被对方识别为爬虫
    • 那么上面的问题如何解决 ?使用多个账号
1.2 requests处理cookie的方法

使用requests处理cookie有三种方法:

  1. cookie字符串放在headers中
  2. 把cookie字典放传给请求方法的cookies参数接收
  3. 使用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 小结
  1. cookie字符串可以放在headers字典中,键为Cookie,值为cookie字符串
  2. 可以把cookie字符串转化为字典,使用请求方法的cookies参数接收
  3. 使用requests提供的session模块,能够自动实现cookie的处理,包括请求的时候携带cookie,获取响应的时候保存cookie

练习3 爬取IP代理,组建代理池 url 自选 (3.5星)(百度ip代理,一抓一大把)

代理高匿测试:http://httpbin.org/ip 或 http://mip.chinaz.com/

参考答案爬取ip代理 提取码:9ghy

2.8 requests模块的其他方法

  1. 掌握requests中cookirJar的处理方法
  2. 掌握requests解决https证书错误的问题
  3. 掌握requests中超时参数的使用
  4. 掌握retrying模块的使用

1 requests中cookirJar的处理方法

使用request获取的resposne对象,具有cookies属性,能够获取对方服务器设置在本地的cookie,但是如何使用这些cookie呢?

1.1 方法介绍
  1. response.cookies是CookieJar类型
  2. 使用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 模块的使用

  1. 使用retrying模块提供的retry模块
  2. 通过装饰器的方式使用,让被装饰的函数反复执行
  3. 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篇】相关推荐

  1. Python3网络爬虫快速入门实战解析(一小时入门 Python 3 网络爬虫)

    Python3网络爬虫快速入门实战解析(一小时入门 Python 3 网络爬虫) https://blog.csdn.net/u012662731/article/details/78537432 出 ...

  2. Python教程:网络爬虫快速入门实战解析

    建议: 请在电脑的陪同下,阅读本文.本文以实战为主,阅读过程如稍有不适,还望多加练习. 网络爬虫简介 网络爬虫,也叫网络蜘蛛(Web Spider).它根据网页地址(URL)爬取网页内容,而网页地址( ...

  3. python3 爬虫实例_【实战练习】Python3网络爬虫快速入门实战解析(上)

    原标题:[实战练习]Python3网络爬虫快速入门实战解析(上) 摘要 使用python3学习网络爬虫,快速入门静态网站爬取和动态网站爬取 [ 前言 ] 强烈建议:请在电脑的陪同下,阅读本文.本文以实 ...

  4. 【读书笔记】Python网络爬虫从入门到实践(第2版)-唐松,爬虫基础体系巩固和常见场景练习

    [概述] 书名:Python网络爬虫从入门到实践(第2版) 作者:唐松 日期:2021年08月01日 读书用时:1568页,100小时,59个笔记 [读书笔记] ◆ 1.2 网络爬虫是否合法 爬虫协议 ...

  5. Python3网络爬虫快速入门实战解析

    Python3网络爬虫快速入门实战解析 标签: python网络爬虫 2017-09-28 14:48 6266人阅读 评论(34) 收藏 举报 分类: Python(26) 作者同类文章X 版权声明 ...

  6. Python3 网络爬虫快速入门实战解析

    点击上方"Python高校",关注 文末干货立马到手 作者:Jack Cui http://cuijiahua.com/blog/2017/10/spider_tutorial_1 ...

  7. beautifulsoup网页爬虫解析_Python3 网络爬虫快速入门实战解析

    点击上方"Python高校",关注 文末干货立马到手 作者:Jack Cui http://cuijiahua.com/blog/2017/10/spider_tutorial_1 ...

  8. python编程入门到实践 百度云-python网络爬虫从入门到实践pdf

    python网络爬虫从入门到实践pdf是一本非常热门的编程教学.这本书籍详细讲解了Python以及网络爬虫相关知识,非常适合新手阅读,需要的用户自行下载吧. Python网络爬虫从入门到实践电子书介绍 ...

  9. python网络爬虫教程-终于明了python网络爬虫从入门到实践

    Python是一款功能强大的脚本语言,具有丰富和强大的库,重要的是,它还具有很强的可读性,易用易学,非常适合编程初学者入门.以下是小编为你整理的python网络爬虫从入门到实践 环境配置:下载Pyth ...

最新文章

  1. 听客来团队scrum敏捷开发工具实践分享
  2. H5 中的 new FileReader() 以及 识别上传的文件是否为图片
  3. 作家百态之二:山南海北
  4. Android学习笔记---HttpClient入门,使用方法,及简介
  5. Stanford机器学习---第十一讲.异常检测
  6. 基于SOLIDWORKS Simulation的有限元分析法实例应用
  7. 2.7 汽车之家口碑爬虫
  8. 腐蚀rust电脑分辨率调多少_腐蚀Rust帧数优化指南 游戏FPS提高方法说明
  9. java学习第114天,p699-706(05/12),完成QQ群发
  10. 舵机弹跳机器人_Nature:蚂蚁机器人弹跳力惊人 还会分工合作
  11. 犹太人的智慧书《塔木德》(Talmud)
  12. 数学分析(1): 实数
  13. Python读取图像数据的常用方法
  14. Android 获取彩信文本内容及 发送时间 发送人
  15. Spring的ioc控制反转
  16. python数据处理与分析(汇总)
  17. 数据挖掘的概念和步骤
  18. 一个实验了解多层内网渗透
  19. 关闭Windows XP系统Beep提示音
  20. 生物信息学技术在罕见病研究中的应用

热门文章

  1. linux内核wifi驱动,基于2.6.35内核的SDIO-WiFi驱动移植
  2. php.ini 中register_globals的ON和Off配置
  3. skype模糊搜索联系人_我越来越在挖掘Skype,我已经厌倦了所有不同的“我”问题。 另外,移动您的Skype联系人。...
  4. 准工业级代码分享:Python用于自动生成EXCEL周期报告
  5. vitepress添加脚注插件
  6. 两万文字详解Pandas DataFrame(持续更新)
  7. c#和java部署pytorch同事识别两个图片_人脸识别漏洞频出?这里有个开源静默活体检测算法,超低运算量、工业级可用...
  8. C语言源代码系列-管理系统之职工工资管理系统
  9. 扁鹊三兄弟——电脑永远无法取代的正确判断
  10. HTML背景图全屏显示