https://blog.51cto.com/u_15858929/6246451
全栈工程师开发手册 (作者:栾鹏)
python教程全解
python数据挖掘库urllib、urllib2、cookie知识全解。本文使用python2.7环境,如果需要使用python3的环境只需要按照下面的对应关系替换即可。
注意:python3.4以后中,将urllib2、urlparse、robotparser并入了urllib模块,并且修改了urllib模块,其中包含了5个子模块,每个子模块中的常用方法如下:
在Pytho2.x中使用import urllib2——-对应的,在Python3.x中会使用import urllib.request,urllib.error。
在Pytho2.x中使用import urllib——-对应的,在Python3.x中会使用import urllib.request,urllib.error,urllib.parse。
在Pytho2.x中使用import urlparse——-对应的,在Python3.x中会使用import urllib.parse。
在Pytho2.x中使用import urlopen——-对应的,在Python3.x中会使用import urllib.request.urlopen。
在Pytho2.x中使用import urlencode——-对应的,在Python3.x中会使用import urllib.parse.urlencode。
在Pytho2.x中使用import urllib.quote——-对应的,在Python3.x中会使用import urllib.request.quote。
在Pytho2.x中使用cookielib.CookieJar——-对应的,在Python3.x中会使用http.CookieJar。
在Pytho2.x中使用urllib2.Request——-对应的,在Python3.x中会使用urllib.request.Request。
python2.7环境,以下的所有程序需要导入以下库
python3.6环境下,以下的所有程序需要导入以下库
本文使用python3.6环境调试
urllib.parse.urlparse模块,网址字符串处理
在python2中是urllib2.urlparse模块。
包含了将网址分解为6元组,将6元组分解为网址,获取指定网址上的链接所代表的绝对网址。
urllib.request.urlretrieve模块:下载读取远程静态文件
在python2中是urllib.urlretrieve模块。
主要包含远程文件的下载,远程文件存储到本地,远程文件的读取,以及http响应的MIME头信息。
所谓的MIME头就是http协议中,数据传输都是以字节流在网线中传递,在一个文件或数据的传递起始部分都有个MIME头,用来描述本次传递的某些属性特点,如图中上面红色框中的内容。下面的红色框为传输的文件内容。
urllib.request.Request模块:获取get方式请求响应流
在python2中是urllib2.Request模块。
所谓get方式,就是将请求数据序列化以后添加到网址中,打开指定网址的过程。
urllib.request.Request模块:获取post方式请求响应流
在python2中是urllib2.Request模块。
post方式就是向指定的网址发送一段数据的仿真,所以请求过程除了请求网址,还有请求数据,两个参数来创建请求对象。
而对于我们想要爬取的网站,如何知道需要发送什么数据呢,需要用到浏览器的监听功能了。
这里以有道翻译为例,我们希望像服务器发送需要翻译的内容,获取翻译的结果,那么应该发送什么样的内容呢。
打开有道翻译的网址http://fanyi.youdao.com/
右键检查(审查元素)-切换到Network切换到网络监听部分。
在左侧翻译区输入你要翻译的内容如“jack”,回车后网页自动翻译,获取了翻译结果“杰克”,同时我们看到在右侧网络监听部分,已经显示出在此过程中所有的信息交互。
我们点击第一个信息交互记录,可以进入此次交互的详情。包括http头(MIME),和请求数据的格式。我们要发送的数据格式就按照图中的格式添加就可以了。
urllib.error异常
urllib.error有两个方法,URLError和HTTPError
URLError是OSError的一个子类,HTTPError是URLError的一个子类,服务器上HTTP的响应会返回一个状态码,根据这个HTTP状态码,我们可以知道我们的访问是否成功。200状态码,表示请求成功,再比如常见的404错误等。
最后值得注意的一点是,如果想用HTTPError和URLError一起捕获异常,那么需要将HTTPError放在URLError的前面,因为HTTPError是URLError的一个子类。如果URLError放在前面,出现HTTP异常会先响应URLError,这样HTTPError就捕获不到错误信息了。
urllib.request.Request模块:控制http头
在python2中是urllib2.Request模块。
很多服务器或代理服务器会查看HTTP头,进而控制网络流量,实现负载均衡,限制不正常用户的访问。所以我们要学会设置HTTP头,来保证一些访问的实现。
网站的HTTP头的设置,可以通过网页右键审查元素中查看,同上图。
HTTP头部分参数说明:
- Upgrade-Insecure-Requests:参数为1。该指令用于让浏览器自动升级请求从http到https,用于大量包含http资源的http网页直接升级到https而不会报错。简洁的来讲,就相当于在http和https之间起的一个过渡作用。就是浏览器告诉服务器,自己支持这种操作,我能读懂你服务器发过来的上面这条信息,并且在以后发请求的时候不用http而用https;
- User-Agent:有一些网站不喜欢被爬虫程序访问,所以会检测连接对象,如果是爬虫程序,也就是非人点击访问,它就会不让你继续访问,所以为了要让程序可以正常运行,我们需要设置一个浏览器的User-Agent;
- Accept:浏览器可接受的MIME类型,可以根据实际情况进行设置;
- Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip。Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间;
- Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到;
- Cookie:这是最重要的请求头信息之一。中文名称为“小型文本文件”或“小甜饼“,指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。定义于RFC2109。是网景公司的前雇员卢·蒙特利在1993年3月的发明。
常见的User Agent
1.Android
Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19
Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Mozilla/5.0 (Linux; U; Android 2.2; en-gb; GT-P1000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
2.Firefox
Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
3.Google Chrome
Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19
4.iOS
Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A101a Safari/419.3
urllib.request.ProxyHandler函数:设置代理服务器,防止限制IP
在python2中是urllib2.ProxyHandler函数。
控制代理服务器,防止服务器限制IP。每隔一段时间换一个代理服务器
代理服务器的ip你可以从网页中自己选择和定期更换
URL:http://www.xicidaili.com/
使用install_opener方法之后,会将程序默认的urlopen方法替换掉。也就是说,如果使用install_opener之后,在该文件中,再次调用urlopen会使用自己创建好的opener。如果不想替换掉,只是想临时使用一下,可以使用opener.open(url),这样就不会对程序默认的urlopen有影响。
编写代码访问http://www.whatismyip.com.tw/,该网站是测试自己IP为多少的网址,服务器会返回访问者的IP。在使用代理服务器以后,访问这里查询本地IP地址的网址的返回结果也会由于代理服务器的存在而随机变化。
下面实现了一个爬虫,爬取http://www.xicidaili.com/ 网站中代理服务器的列表。
有了上面的列表就可以直接从数组中随机选择一个代理服务器。
urllib.request.HTTPCookieProcessor函数:设置cookie
在python2中是urllib2.HTTPCookieProcessor函数
cookie模块:将cookie写入文件
ookie.save的参数说明:
ignore_discard的意思是即使cookies将被丢弃也将它保存下来;
ignore_expires的意思是如果在该文件中cookies已经存在,则覆盖原文件写入。
在这里,我们将这两个全部设置为True。
运行之后,cookies将被保存到cookie.txt文件中。我们可以查看自己查看下cookie.txt这个文件的内容。
cookie模块:从文件中读取cookie
cookie模块:利用cookie模拟登陆
创建一个带有cookie的opener,在访问登录的URL时,将登录后的cookie保存下来,然后利用这个cookie来访问其他网址
现在很多网站需要登陆后才能访问,如知乎,地址https://www.zhihu.com
在没有登陆时访问这个网址,只能出现登陆界面
如果登陆以后,在访问这个网址,就会出现文章列表。
这是因为访问此地址,知乎服务器会查询请求cookie,如果请求cookie没有用户信息,就证明没有登陆,就会返回登陆界面,如果有cookie信息就会返回文章列表界面,同时包含用户的其他信息。所以首先需要让自己的请求中能带有包含自己信息的cookie。这一步通过登陆来实现。
在登陆界面,通过post将用户账号密码发送给服务器,服务器会将用户信息以cookie的形式返回给用户,用户在下次请求时,就会自动将这个cookie添加到请求http头中,这样下次再访问时,服务器就知道这个用户已经登陆了。
所以在使用cookie模拟登陆,需要两步,第一步是获取cookie,第二步是将cookie添加到http中,模拟用户已经存在的方式请求文章。
第一步,登陆获取cookie(通过post向指定网址发送数据,获取返回cookie即可)
对于发送数据需要添加的post数据和http头可以通过审查元素监听。
由于浏览器的监听在跳转到新的网页就会清空重新监听,所以在登陆到文章列表页面,浏览先监听了登陆页面的数据,后清空监听记录,重新监听文章列表页面的数据。不能及时记录下载登陆界面发送的请求数据,所以建议使用fiddle监听数据。
不过也不是没有办法,监听区红色的记录开关按钮,可以及时的阻止监听。
这里在点击登陆后,我立刻点击了浏览监听中的红色记录按钮,拦截了登陆界面的数据。
可以看到需要发送的数据除了phone_num手机号、password密码、captcha_type验证码类型(选择不同的登陆方式需要发送的数据类型可以不同),还有一个_xsrf,这个字段是在登陆网页源代码中
所以在发送post前还要获取网页源代码解析这个字段。
第二步、通过获取的cookie,模拟已经登陆的状态。这样再次访问知乎网址,就能获取文章了。
访问文章需要的http头可以通过审查元素查看。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/python/309030.html