赞
踩
一、urllib.parse模块
上篇文章学到了data参数,但是data参数进行传递的前要先进行转换格式,这里用到了urllib.parse.urlencode()
(1)urllib.parse.urlencode() :将字典形式(key-value)的数据转化成查询字符串
(2)这里还要介绍一个json模块:
JSON(JavaScript Object Notation) :是一种传递对象的语法,对象可以是name/value对,数组和其他对象。
函数 | 功能 |
json.dumps | 将 Python 对象编码成 JSON 字符串 |
json.loads | 将已编码的 JSON 字符串解码为 Python 对象 |
在这次的实例中被用来把网页返回的response的字典转换为python对象。
(3)还要提到一个urllib.request.Request():
urllib.request.Request():传送headers(请求头)等信息。(urlopen()可以发送基本的请求但是这几个参数远远不够)
使用请求头headers的原因:在使用python爬虫爬取数据的时候,经常会遇到一些网站的反爬虫措施,一般就是针对于headers中的User-Agent。如果没有对headers进行设置,User-Agent会声明自己是python脚本,而如果网站有反爬虫的想法的话,必然会拒绝这样的连接。而修改headers可以将自己的爬虫脚本伪装成浏览器的正常访问,来避免这一问题。
(4)这里的实例是爬百度翻译。(不要一味看别人的代码,毕竟网站也在不断的变化,掌握方法,学会处理问题)
启示:
1 学会去网页源代码找自己要的数据:一定要知道怎么去找data数据,方法:打开百度翻译的审查元素,打开network查看,HXR里面选择最后一个文件headers最低部就可以找到data字典对应的。然后要去理解其中的含义。
2 关于URL遇到的问题:最开始的时候,我是直接用(http://fanyi.baidu.com)网址,结果返回的不是字典序而是网页代码,于是json.loads那里就开始报错了,一开始没输出来看上网查以为是BOM头的问题,后来才知道是网址的问题。打开的百度翻译的网页要打开的手机版的(http://fanyi.baidu.com/basetrans),打开网页版的(http://fanyi.baidu.com/v2transapi)会返回{“error”:997,”from”:”en”,……}。
代码:
- import urllib.request
- import urllib.parse
- import json
- import codecs
- content = input("请输入要翻译的内容:")
- data = {}
- #打开network查看,HXR里面选择最后一个文件headers最低部就可以找到data
- data['from'] = 'en'#英文
- data['to'] = 'zh'#中文
- #英译中,这里是可以选择的
- data['query'] = content
- data['transtype'] = 'enter'
- data['sipel_means_flag'] = '3'
- data = urllib.parse.urlencode(data).encode("utf-8")
- #data应该是bytes,所以上传给server时需要转换成ascii数据。
- head ={}
- head['User-Agent'] = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Mobile Safari/537.36'
- url = "http://fanyi.baidu.com/basetrans"
- rep = urllib.request.Request(url,data,head)
- response = urllib.request.urlopen(rep)
- html = response.read()
- '''
- 原先用http://fanyi.baidu.com/v2transapi一直报错以为是BOM头的问题
- 所以写了:(除去BOM头)
- if html[:3] == codecs.BOM_UTF8:
- html = html[3:]
- 结果是打开这个网页一看就是个报错的网址,返回的是{“error”:997,”from”:”en”,……}
- 上网查了一下说是:打开界面发现headers中sign是动态生成的所以考虑用手机版网页
- 也就是上面提到的http://fanyi.baidu.com/basetrans
- '''
- html = html.decode("utf-8")
- translat_result = json.loads(html)
- #返回的信息是字典可以用内置模块json,将已编码的 JSON 字符串解码为 Python 对象
- rst = translat_result["trans"][0]["dst"]
- print("翻译的结果是:%s"%rst)
(5)补充一个知识点,如何隐藏身份不被反爬虫,使用代理IP:
为什么要使用代理IP:User-Agent已经设置好了,但是代码访问的速度是很快的,如果用代码一直访问一个网站,一个固定IP访问的频率就会很高,而人的访问速度是没有那么快的,而且高频率的访问会给服务器带来压力。所以有一些网站会设置一个IP访问频率的阈值,来判断是不是人访问。
解决的办法,就是一种是设置延时还有一种就是代理IP。网络中的身份之一就是IP,访问太多次就会被网站拒之门外,这时候就可以用代理IP(相当于换个ip)继续去访问。
在写代码前,先去一些代理IP的网站(例如 西刺代理 全国代理ip)选好一个IP地址。
我选了:116.225.110.126:8888
这里要用到的重要代码介绍:
opener:
为什么使用opener:之前一直使用的是urlopen(url)这种形式来打开网页,它是一个特殊的opener(也就是模块帮我们建好的),传入的参数仅仅是url,data,timeout。但是基本的urlopen()方法不支持debug模式和代理、cookie等其他的HTTP/HTTPS高级功能。如果要实现这些请求的话,我们需要自己定义Handler和opener。
讲到opener还要补充介绍一下handlers:
handlers:Openers使用处理器handlers,所有的“繁重”工作由handlers处理。每个handlers知道如何通过特定协议打开URLs,或者如何处理URL打开时的各个方面。
如何使用opener:可以使用相关的 Handler处理器urllib.request.ProxyHandler()来创建特定功能的处理器对象;
(urllib.request.ProxyHandler(proxies):设置代理服务器。proxies为字典)
然后通过 urllib.request.build_opener()方法使用这些处理器对象,创建自定义opener对象;
(urllib.request.build_opener():用来创建opener对象)
使用自定义的opener对象,调用open()方法发送请求。
(opener.open():发送请求使用自定义的代理,但urlopen()则不使用自定义代理。)
或者用 urllib.install_opener()方法处理opener,然后还是用urlopen()发送请求。
(urllib.install_opener():将opener应用到全局,之后所有的,不管是opener.open()还是urlopen() 发送请求,都将使用自定义代理。)
实例代理ip访问百度:
- import urllib.request
-
- url = 'https://www.baidu.com'
- proxy = {'http':'116.225.110.126:'}
- proxy_support = urllib.request.ProxyHandler(proxy)
- opener = urllib.request.build_opener(proxy_support)
- opener.addheaders = [('User-Agent','Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Mobile Safari/537.36')]
- req = urllib.request.Request(url)
- response = opener.open(req)
- html = response.read().decode("utf-8")
- print(html)
如果返回的是由于目标机器积极拒绝就说明ip可能是无效的。
下一篇会继续学习urllib...
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。