1、第 1 页 共 191 页Python 爬虫入门三之 Urllib 库的基本使用Python 崔庆才 5 个月前 (02-12) 13660 13 评论那么接下来,小伙伴们就一起和我真正迈向我们的爬虫之路吧。1. 分分钟扒一个网页下来怎样扒网页呢?其实就是根据 URL 来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面, 但是其实是由浏览器解释才呈现出来的, 实质它是一段 HTML 代码,加 JS、 CSS,如果把网页比作一个人,那么 HTML 便是他的骨架, JS便是他的肌肉, CSS便是它的衣服。 所以最重要的部分是存在于 HTML中的,下面我们就写个例子来扒一个网页下来。1
2、2 3 4 import urllib2response = urllib2 .urlopen (“http:/“ )print response .read ()是的你没看错,真正的程序就两行,把它保存成 demo.py,进入该文件的目录,执行如下命令查看运行结果,感受一下。1 python demo .py第 2 页 共 191 页看,这个网页的 源码 已经被我们扒下来了,是不是很酸爽?2. 分析扒网页的方法那么我们来分析这两行代码,第一行1 response = urllib2 .urlopen (“http:/“ )首先我们调用的是 urllib2 库里面的 urlopen 方法, 传
3、入一个 URL , 这个网址是百度首页,协议是 HTTP 协议,当然你也可以把 HTTP 换做 FTP,FILE,HTTPS 等等,只是代表了一种 访问控制 协议, urlopen 一般接受三个参数,它的参数如下:第 3 页 共 191 页1 urlopen (url, data, timeout )第一个参数 url 即为 URL ,第二个参数 data是访问 URL 时要传送的数据,第三个 timeout 是设置超时时间。第二三个参数是可以不传送的, data默认为空 None, timeout 默认为 socket._GLOBAL_DEFAULT_TIMEOUT 第一个参数 URL 是必
4、须要传送的,在这个例子里面我们传送了百度的 URL,执行 urlopen 方法之后,返回一个 response对象,返回信息便保存在这里面。1 print response .read ()response对象有一个 read 方法,可以返回获取到的网页内容。如果不加 read直接打印会是什么?答案如下:1 直接打印出了该对象的描述,所以记得一定要加 read方法,否则它不出来内容可就不怪我咯!3. 构造 Requset其实上面的 urlopen 参数可以传入一个 request请求 ,它其实就是一个 Request类的实例,构造时需要传入 Url,Data 等等的内容。比如上面的两行代码,我
5、们可以这么改写第 4 页 共 191 页1 2 3 4 5 import urllib2request = urllib2 .Request (“http:/“ )response = urllib2 .urlopen (request )print response .read ()运行结果是完全一样的,只不过中间多了一个 request对象,推荐大家这么写,因为在构建请求时还需要加入好多内容, 通过构建一个 request, 服务器 响应请求得到应答,这样显得逻辑上清晰明确。4.POST和 GET数据传送上面的程序演示了最基本的网页抓取, 不过, 现在大多数网站都是动态网页, 需要你动态地
6、传递参数给它,它做出对应的响应。所以,在访问时,我们需要传递数据给它。最常见的情况是什么?对了,就是登录注册的时候呀。把数据用户名和密码传送到一个 URL ,然后你得到服务器处理之后的响应,这个该怎么办?下面让我来为小伙伴们揭晓吧!数据传送分为 POST 和 GET 两种方式,两种方式有什么区别呢?最重要的区别是 GET 方式是直接以链接形式访问,链接中包含了所有的参数,当然如果包含了密码的话是一种不安全的选择, 不过你可以直观地看到自己提交了什么内容。 POST 则不会在网址上显示所有的参数,不过如果你想直接查看提交了什么就不太方便了,大家可以酌情选择。POST方式:上面我们说了 data参
7、数是干嘛的?对了,它就是用在这里的,我们传送的数据就是这个参数 data,下面 演示 一下 POST方式。1 import urllib第 5 页 共 191 页2 3 4 5 6 7 8 9 import urllib2values = “username“ :““ ,“password“ :“XXXX“ data = urllib .urlencode (values )url = “https:/ = urllib2 .Request (url,data )response = urllib2 .urlopen (request )print response .read ()我们引入了
8、 urllib 库, 现在我们模拟登陆 CSDN, 当然上述代码可能登陆不进去,因为还要做一些设置头部 header的工作,或者还有一些参数没有设置全,还没有提及到在此就不写上去了, 在此只是说明登录的原理。 我们需要定义一个字典,名字为 values, 参数我设置了 username和 password, 下面利用 urllib 的 urlencode方法将字典编码,命名为 data,构建 request时传入两个参数, url 和 data,运行程序, 即可实现登陆, 返回的便是登陆后呈现的页面内容。 当然你可以自己搭建一个 服务器 来测试一下。注意上面字典的定义方式还有一种,下面的写法是
9、等价的1 2 3 4 5 6 7 import urllibimport urllib2values = values username = ““values password = “XXXX“data = urllib .urlencode (values )第 6 页 共 191 页8 9 10 11 url = “http:/ from =http:/ = urllib2 .Request (url ,data )response = urllib2 .urlopen (request )print response .read ()以上方法便实现了 POST 方式的传送GET方式:至于
10、 GET 方式我们可以直接把参数写到网址上面,直接构建一个带参数的 URL出来即可。1 2 3 4 5 6 7 8 9 10 11 12 import urllibimport urllib2values =values username = ““values password =“XXXX“data = urllib .urlencode (values )url = “http:/ = url + “?“ +datarequest = urllib2 .Request (geturl )response = urllib2 .urlopen (request )print response
11、 .read ()你可以 print geturl,打印输出一下 url,发现其实就是原来的 url 加?然后加编码后的参数第 7 页 共 191 页1 http:/ MSIE 5.5; Windows NT)values = username : cqc , password : XXXX headers = User-Agent : user _agent data = urllib .urlencode (values )request = urllib2 .Request (url , data , headers )response = urllib2 .urlopen (reque
12、st )page = response .read ()这样, 我们设置了一个 headers, 在构建 request时传入, 在请求时, 就加入了 headers传送,服务器若识别了是浏览器发来的请求,就会得到响应。另外,我们还有 对付 ” 反盗链 ” 的方式,对付防盗链,服务器会识别 headers中的referer是不是它自己, 如果不是, 有的服务器不会响应, 所以我们还可以在 headers中加入 referer 例如我们可以构建下面的 headers 1 2 head ers = User-Agent : Mozilla/4.0 (compatible; MSIE 5.5; Wi
13、ndows NT) ,Referer :http:/ 同上面的方法,在传送请求时把 headers 传入 Request参数里,这样就能应付防盗链了。另外 headers的一些属性,下面的需要特别注意一下:User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。application/ xml : 在 XML RPC,如 RESTful/SOAP 调用时使用application/json : 在 JSON RPC 调用时使用applic
14、ation/x-www-form-urlencoded : 浏览器提交 Web 表单时使用在使用服务器提供的 RESTful 或 SOAP 服务时, Content-Type 设置错误会导致服务器拒绝服务第 10 页 共 191 页其他的有必要的可以审查浏览器的 headers内容, 在构建时写入同样的数据即可。2. Proxy (代理)的设置urllib2 默认会使用 环境变量 http_proxy 来设置 HTTP Proxy。假如一个网站它会检测 某一段时间某个 IP 的访问次数,如果访问次数过多,它会禁止你的访问。所以你可以设置一些 代理服务器 来帮助你做工作,每隔一段时间换一个代理,
15、网站君都不知道是谁在捣鬼了,这酸爽!下面一段代码说明了 代理 的设置用法1 2 3 4 5 6 7 8 9 import urllib2enable_proxy = Trueproxy_handler = urllib2 .ProxyHandler (“http“ : http:/some-:8080 )null_proxy_handler = urllib2 .ProxyHandler ()if enable_proxy :opener = urllib2 .build_opener (proxy_handler )else :opener = urllib2 .build_opener (null_proxy_handler )urllib2 .install_opener (open er)3. Timeout 设置上一节已经说过 urlopen 方法了,第三个参数就是 timeout 的设置,可以设置等待多久超时,为了解决一些网站实在响应过慢而造成的影响。例如下面的代码 ,如果第二个参数 data为空那么要特别指定是 timeout 是多少, 写明形参,如果 data已经传入,则不必 声明 。