作者:xiaoyu

微信公众号:Python数据科学

知乎:Python数据分析师

前情回顾,urllib的基本用法

urllib库的基本组成

利用最简单的urlopen方法爬取网页html

利用Request方法构建headers模拟浏览器操作

error的异常操作

具体内容参见Python从零学爬虫。urllib库除了以上基础的用法外,还有很多高级的功能,可以更加灵活的适用在爬虫应用中,比如:

使用HTTP的POST请求方法向服务器提交数据实现用户登录

使用代理IP解决防止反爬

设置超时提高爬虫效率

解析URL的方法

本次将会对这些内容进行详细的分析和讲解。

POST请求

POST是HTTP协议的请求方法之一,也是比较常用到的一种方法,用于向服务器提交数据。博主先介绍进行post请求的一些准备工作,然后举一个例子,对其使用以及更深层概念进行详细的的剖析。

POST请求的准备工作

既然要提交信息给服务器,我们就需要知道信息往哪填,填什么,填写格式是什么?带这些问题,我们往下看。

同样提交用户登录信息(用户名和密码),不同网站可能需要的东西不一样,比如淘宝反爬机制较复杂,会有其它一大串的额外信息。这里,我们以豆瓣为例(相对简单),目标是弄清楚POST是如何使用的,复杂内容会在后续实战部分与大家继续分享。

抛出上面像淘宝一样需要的复杂信息,如果仅考虑用户名和密码的话,我们的准备工作其实就是要弄明白用户名和密码标签的属性name是什么,以下两种方法可以实现。

浏览器F12查看element获取

废话不多说了,让我们看看到底如何找到name?

1. 浏览器F12

通过浏览器F12元素逐层查看到(我是用的Chrome),邮箱/手机号标签的name="form_email", 密码的标签name="form_email",如下图红框所示。

但要说明的是,两个标签的name名称并不是固定的,上面查看的name名称只是豆瓣网站定义的,不代表所有。其它的网站可能有会有不同的名称,比如name="username", name="password"之类的。因此,针对不同网站的登录,需要每次查看name是什么。

2. 通过fiddler抓包工具

博主推荐使用fiddler工具,非常好用。爬虫本身就是模拟浏览器工作,我们只需要知道浏览器是怎么工作的就可以了。

fiddler会帮助我们抓取浏览器POST请求的所有内容,这样我们得到了浏览器POST的信息,把它填到爬虫程序里模拟浏览器操作就OK了。另外,也可以通过fiddler抓到浏览器请求的headers,非常方便。

安装fiddler的小伙伴们注意:fiddler证书问题的坑(无法抓取HTTPs包),可以通过Tools —> Options —>HTTPS里面打勾Decrypt HTTPS traffic修改证书来解决。否则会一直显示抓取 Tunnel 信息包...

好了,完成了准备工作,我们直接上一段代码理解下。

POST请求的使用

# coding: utf-8

import urllib.request

import urllib.error

import urllib.parse

# headers 信息,从fiddler上或你的浏览器上可复制下来

headers = {'Accept': 'text/html,application/xhtml+xml,

application/xml;q=0.9,image/webp,image/apng,

*/*;q=0.8',

'Accept-Language': 'zh-CN,zh;q=0.9',

'User-Agent': 'Mozilla/5.0 (Windows NT 6.3;

Win64; x64) AppleWebKit/537.36

(KHTML, like Gecko)Chrome/48.0

.2564.48 Safari/537.36'

}

# POST请求的信息,填写你的用户名和密码

value = {'source': 'index_nav',

'form_password': 'your password',

'form_email': 'your username'

}

try:

data = urllib.parse.urlencode(value).encode('utf8')

response = urllib.request.Request(

'https://www.douban.com/login', data=data, headers=headers)

html = urllib.request.urlopen(response)

result = html.read().decode('utf8')

print(result)

except urllib.error.URLError as e:

if hasattr(e, 'reason'):

print('错误原因是' + str(e.reason))

except urllib.error.HTTPError as e:

if hasattr(e, 'code'):

print('错误编码是' + str(e.code))

else:

print('请求成功通过。')

运行结果:

推荐、评论和价格比较,以及城市独特的文化生活。">

.....

window.attachEvent('onload', _ga_init);

}

注意:复制header的时候请去掉 这一项'Accept-Encoding':' gzip, deflate, 否则会提示decode的错误。

POST请求代码分析

我们来分析一下上面的代码,与urllib库request的使用基本一致,urllib库request的基本用法可参考上篇文章Python从零学爬虫,这里多出了post的data参数和一些解析的内容,着重讲解一下。

data = urllib.parse.urlencode(value).encode('utf8')

这句的意思是利用了urllib库的parse来对post内容解析,为什么要解析呢?

这是因为post内容需要进行一定的编码格式处理后才能发送,而编码的规则需要遵从RFC标准,百度了一下RFC定义,供大家参考:

*

Request ForComments(RFC),是一系列以编号排定的文件。文件收集了有关互联网相关信息,以及UNIX和互联网社区的软件文件。目前RFC文件是由InternetSociety(ISOC)赞助发行。基本的互联网通信协议都有在RFC文件内详细说明。RFC文件还额外加入许多的论题在标准内,例如对于互联网新开发的协议及发展中所有的记录。因此几乎所有的互联网标准都有收录在RFC文件之中。

*

而parse的urlencode方法是将一个字典或者有顺序的二元素元组转换成为URL的查询字符串(说白了就是按照RFC标准转换了一下格式)。然后再将转换好的字符串按UTF-8的编码转换成为二进制格式才能使用。

注:以上是在Python3.x环境下完成,Python3.x中编码解码规则为 byte—>string—>byte的模式,其中byte—>string为解码,string—>byte为编码

代理IP

代理IP的使用

为什么要使用代理IP?因为各种反爬机制会检测同一IP爬取网页的频率速度,如果速度过快,就会被认定为机器人封掉你的IP。但是速度过慢又会影响爬取的速度,因此,我们将使用代理IP取代我们自己的IP,这样不断更换新的IP地址就可以达到快速爬取网页而降低被检测为机器人的目的了。

同样利用urllib的request就可以完成代理IP的使用,但是与之前用到的urlopen不同,我们需要自己创建订制化的opener。什么意思呢?

urlopen就好像是opener的通用版本,当我们需要特殊功能(例如代理IP)的时候,urlopen满足不了我们的需求,我们就不得不自己定义并创建特殊的opener了。

request里面正好有处理各种功能的处理器方法,如下:

ProxyHandler, UnknownHandler, HTTPHandler,

HTTPDefaultErrorHandler, HTTPRedirectHandler,

FTPHandler, FileHandler, HTTPErrorProcessor, DataHandler

我们要用的是第一个ProxyHandler来处理代理问题。

让我们看一段代码如何使用。

# coding:utf-8

import urllib.request

import urllib.error

import urllib.parse

# headers信息,从fiddler上或浏览器上可复制下来

headers = {'Accept': 'text/html,application/xhtml+xml,

application/xml;q=0.9,image/webp,image/apng,

*/*;q=0.8',

'Accept-Language': 'zh-CN,zh;q=0.9',

'User-Agent': 'Mozilla/5.0 (Windows NT 6.3;

Win64;

x64) AppleWebKit/537.36 (KHTML,

like Gecko)Chrome/48.0.2564.48

Safari/537.36'

}

# POST请求的信息

value = {'source': 'index_nav',

'form_password': 'your password',

'form_email': 'your username'

}

# 代理IP信息为字典格式,key为'http',value为'代理ip:端口号'

proxy = {'http': '115.193.101.21:61234'}

try:

data = urllib.parse.urlencode(value).encode('utf8')

response = urllib.request.Request(

'https://www.douban.com/login', data=data, headers=headers)

# 使用ProxyHandler方法生成处理器对象

proxy_handler = urllib.request.ProxyHandler(proxy)

# 创建代理IP的opener实例

opener = urllib.request.build_opener(proxy_handler)

# 将设置好的post信息和headers的response作为参数

html = opener.open(response)

result = html.read().decode('utf8')

print(result)

except urllib.error.URLError as e:

if hasattr(e, 'reason'):

print('错误原因是' + str(e.reason))

except urllib.error.HTTPError as e:

if hasattr(e, 'code'):

print('错误编码是' + str(e.code))

else:

print('请求成功通过。')

在上面post请求代码的基础上,用自己创建的opener替换urlopen即可完成代理IP的操作,代理ip可以到一些免费的代理IP网站上查找,博主整理出几个,如:

运行得到的结果与使用本机IP一样。

代理IP代码分析

# 这个代理IP数据类型为字典,如果是http协议,key值就为**"http"**,value值应为**"代理IP:端口号"的格式**。

proxy = {'http': '115.193.101.21:61234'}

# 使用ProxyHandler方法创建proxy处理器对象

proxy_handler = urllib.request.ProxyHandler(proxy)

# 创建代理IP的opener实例,参数为proxy处理器对象

opener = urllib.request.build_opener(proxy_handler)

# 用代理IP的opener打开指定状态的URL信息

html = opener.open(response)

超时

设置超时的目的是为了防止爬取网站的时候,等待时间过长而导致效率的降低。有效的超时设置可以强制结束等待而进行下一次的爬取,下面来一段代码看如何使用。

# coding:utf-8

import urllib.request

import urllib.error

import urllib.parse

import socket

# headers信息,从fiddler上或浏览器上可复制下来

headers = {'Accept': 'text/html,application/xhtml+xml,

application/xml;q=0.9,image/webp,image/apng,

*/*;q=0.8',

'Accept-Language': 'zh-CN,zh;q=0.9',

'User-Agent': 'Mozilla/5.0 (Windows NT 6.3;

Win64;

x64) AppleWebKit/537.36

(KHTML, like Gecko)Chrome/48.0

.2564.48 Safari/537.36'

}

# POST请求的信息

value = {'source': 'index_nav',

'form_password': 'your password',

'form_email': 'your username'

}

# 代理IP为字典格式,key为'http',value为'代理ip:端口号'

proxy = {'http': '115.193.101.21:61234'}

# 设置超时为2秒,单位为秒

timeout = 2

try:

# 设置socket超时

socket.setdefaulttimeout(timeout)

data = urllib.parse.urlencode(value).encode('utf8')

response = urllib.request.Request(

'https://www.douban.com/login', data=data, headers=headers)

# 使用ProxyHandler方法生成处理器对象

proxy_handler = urllib.request.ProxyHandler(proxy)

# 创建代理IP的opener实例

opener = urllib.request.build_opener(proxy_handler)

# 将设置好的post信息和headers的response作为参数

html = opener.open(response)

result = html.read().decode('utf8')

print(result)

except urllib.error.URLError as e:

if hasattr(e, 'reason'):

print('错误原因是' + str(e.reason))

except urllib.error.HTTPError as e:

if hasattr(e, 'code'):

print('错误编码是' + str(e.code))

except socket.timeout:

print('socket超时')

else:

print('请求成功通过。')

在post和代理IP使用的基础上又增加了超时的使用。

# 设置超时为2秒,单位为秒

timeout = 2

#设置socket超时时间,如果不设置,则会使用默认时间。

socket.setdefaulttimeout(timeout)

# 同时对socket超时timeout的错误设置了异常,timeout错误属于OSerror的子类,时间超出指定timeout就会提示socket超时。

except socket.timeout:

print('socket超时')

urllib库parse解析

除了上面提到的urlencode方法,urllib库的parse中还有很多其它的方法可以使用,如:

#urlparse:把URL解析成6个部分

:///;?#

#urlsplit:把URL解析成5个部分

:///?#

# urlunsplit,urlunparse:进行URL的重组

# 还有urljoin,urldefrag等。

更多用法可以查找官方request源码,也会在后续实战例子中陆续使用介绍。

总结

主要介绍了urllib库的一些高级使用用法:

POST请求的准备和使用方法

代理IP的使用

超时的使用

parse解析

关注微信公众号Python数据科学,获取 120G 人工智能 学习资料。

python urllib.request 爬虫 数据处理-Python爬虫学习之(二)| urllib进阶篇相关推荐

  1. python urllib.request 爬虫 数据处理-python 爬虫之 urllib库

    文章更新于:2020-03-02 注:代码来自老师授课用样例. 一.初识 urllib 库 在 python2.x 版本,urllib 与urllib2 是两个库,在 python3.x 版本,二者合 ...

  2. amazeui学习笔记二(进阶开发2)--Web组件简介Web Component

    amazeui学习笔记二(进阶开发2)--Web组件简介Web Component 一.总结 1.amaze ui:amaze ui是一个web 组件, 由模板(hbs).样式(LESS).交互(JS ...

  3. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  4. 【FastAPI 学习十二】定时任务篇 (移步博客园或个人网站 无广告,界面清爽整洁)

    声明 目前个人放弃CSDN平台,文章只发布于个人网站和博客园 博客园地址 [FastAPI 学习十二]定时任务篇

  5. python urllib.request 爬虫 数据处理-python之爬虫(三) Urllib库的基本使用

    什么是Urllib Urllib是python内置的HTTP请求库 包括以下模块 urllib.request 请求模块 urllib.error 异常处理模块 urllib.parse url解析模 ...

  6. python urllib.request 爬虫 数据处理-Python网络爬虫(基于urllib库的get请求页面)

    一.urllib库 urllib是Python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求.其常被用到的子模块在Python3中的为urllib.request和urllib. ...

  7. python urllib.request 爬虫 数据处理-python爬虫 urllib模块url编码处理

    案例:爬取使用搜狗根据指定词条搜索到的页面数据(例如爬取词条为"周杰伦'的页面数据) import urllib.request # 1.指定url url = 'https://www.s ...

  8. python urllib.request 爬虫 数据处理-python爬虫 urllib模块url编码处理详解

    案例:爬取使用搜狗根据指定词条搜索到的页面数据(例如爬取词条为"周杰伦'的页面数据) import urllib.request # 1.指定url url = 'https://www.s ...

  9. python urllib.request 爬虫 数据处理-python爬虫1--urllib请求库之request模块

    urllib为python内置的HTTP请求库,包含四个模块: request:最基本的HTTP请求模块, 只需要传入URL和参数 error:异常处理模块 parse:工具模块,处理URL,拆分.解 ...

最新文章

  1. 7.1.1 [Enterprise Library]缓存应用程序块场景和目标
  2. 我的世界java下载1.13_Minecraft Java版 1.13.1-pre2 发布
  3. spring2.0和spring2.5及以上版本的jar包区别 spring jar 包详解
  4. vue $set修改对象
  5. Vue前后端对接时判断是否与后端连接成功
  6. php设置session 生命周期,设置session的生命周期(php)
  7. ECShop如何设置默认的配送方式和支付方式
  8. [转载] dataframe中有关inf的处理技巧
  9. opencv程序在未安装opencv环境下运行方法总结
  10. 关于“超时时间已到”的问题
  11. python可视化界面开发实例-Python可视化界面编程入门
  12. “暖男”经济学:创业者最后的增长红利?
  13. 网页对联广告代码效果大全
  14. 陈丽莎计算机科学与技术专业,关于表彰我校成人高等学历教育2015届毕业生学习奖和优秀学生干部获奖者的通知...
  15. python制作气温分布图_基于Python的多种形式气温分布图自动绘制
  16. kali安装小企鹅输入法
  17. High Scalability创始人Todd Hoff:Facebook网络性能的秘密武器
  18. 中国药典 android,中国药典在线查询_中国药典v2.05.03安卓版
  19. 新媒体环境下“沉默的双螺旋”
  20. 春江花月夜 唐 张若虚

热门文章

  1. golang LMDB入门例子——尼玛,LMDB的文档真的是太少了
  2. JSP中 JSTL和EL标签的使用
  3. Django框架(二十)—— Django rest_framework-认证组件
  4. 2018 icpc 徐州现场赛G-树上差分+组合数学-大佬的代码
  5. 使用信号量实现进程间同步
  6. ROS学习手记 - 2.1: Create and Build ROS Package 生成包(Python)
  7. 软件工程 speedsnail 冲刺3
  8. Android使用RxJava+Retrofit2+Okhttp+MVP练习的APP
  9. LruCache缓存机制
  10. JDBC驱动程序的四种方式