网络爬虫之urllib2模块

May 28, 2018 Python学习 访问: 62 次

我感觉不如requests

引入该模板

import urllib2

最简单的访问并读取的例子(网页的内容)

import urllib2
url = "http://127.0.0.1/decode/index.php"
r = urllib2.urlopen(url)
print r.read()
结果
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>工具</title>
</head>
<body>
        <table align="center">
        <form action="ha.php" method="post">
        <tr>   <td>base64加密:</td>       <td><input type="text" name="$str_1"></td>    </tr>
        <br>
        <tr>   <td>base64解密:</td>       <td><input type="text" name="$str_2"></td>    </tr>
        <br>
        <tr>   <td>md5--32位加密:</td>     <td><input type="text" name="$str_3"></td>    </tr>
        <br>
        <tr>   <td>md5--16位加密:</td>     <td><input type="text" name="$str_6"></td>    </tr>
        <br>
        <tr>   <td>url编码:</td>           <td><input type="text" name="$str_4"></td>    </tr>
        <br>
        <tr>   <td>url解码:</td>           <td><input type="text" name="$str_5"></td>    </tr>
        <br>
        <tr>   <td>小写转大写:</td>         <td><input type="text" name="$str_7"></td>    </tr>
        <br>
        <tr>   <td>大写转小写:</td>         <td><input type="text" name="$str_8"></td>    </tr>
        <br>
        <tfoot><tr>   <td> </td>                  <td style="background: red"><input type="submit" value="ok"></td></tr></tfoot>
        </form>
        </table>
</body>
</html>

读取页面的header头部的信息

import urllib2
url = "http://127.0.0.1/decode/index.php"
r = urllib2.urlopen(url)
print r.headers
结果
Date: Wed, 23 May 2018 13:31:19 GMT
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45
X-Powered-By: PHP/5.4.45
Content-Length: 1140
Connection: close
Content-Type: text/html

urlopen(url,data,timeout)

第一个参数url即为URL,第二个参数data是访问URL时要传送的数据,第三个timeout是设置超时时间,data默认为空None,timeout默认为 socket._GLOBAL_DEFAULT_TIMEOUT

==该函数返回的是一个对象,其中有一个read()的成员函数,该成员函数的作用是读取抓取到网页的内容==

构造Request

import urllib2
request = urllib2.Request("http://www.baidu.com")
response = urllib2.urlopen(request)
print response.read()
推荐这么写,因为在构建请求时还需要加入好多内容,通过构建一个request,服务器响应请求得到应答,这样显得逻辑上清晰明确。

POST请求

import urllib2
import urllib
url = "http://127.0.0.1/decode/ha.php"
values = {'str_1':'123'}
data = str(values)
print data
res = urllib2.Request(url,data)
r = urllib2.urlopen(res)
print r.read()
结果
{'str_1': '123'}
<!DOCTYPE html>
<html>
<head>
    <title>明哥工具</title>
</head>
<body>
</body>
</html>
<br><br><br><br><br><br><br><center><a href='index.php'>返回</a></center>
可以发现并没有请求成功
若加上urllib中的urlencode
import urllib2
import urllib
url = "http://127.0.0.1/decode/ha.php"
values = {'str_1':'123'}
data = urllib.urlencode(values)
print data
res = urllib2.Request(url,data)
r = urllib2.urlopen(res)
print r.read()
结果
str_1=123
<!DOCTYPE html>
<html>
<head>
    <title>明哥工具</title>
</head>
<body>
</body>
</html>
base64加密:      MTIz<br><br><br><br><br><br><br><center><a href='index.php'>返回</a></center>
可以发现请求成功

区别

urllib.urlencode()可以将参数转化为所需要的形式
import urllib2
import urllib
url = "http://127.0.0.1/decode/ha.php"
values = {'str_1':'123'}
data = str(values)
print data
data = urllib.urlencode(values)
print data
结果
{'str_1': '123'}
str_1=123

post字典的定义方式有两种

1. values= {'key_1':'value_1','key_2':'value_2'}
2. values = {}   #定义values为一个数组
   values['key_1']=value_1
   values['key_2']=value_2
此上虽说是两种方法,但是意思都是将参数以一个数组的形式给出,并且都需要用到urllib.urlencode()这个函数来转换一下

GET请求

至于GET方式我们可以直接把参数写到网址上面,直接构建一个带参数的URL出来
import urllib
import urllib2
url = 'http://127.0.0.1/ha.php'
values = {'key_1':'value_1','key_2':'value_2'}
data = urllib.urlencode(values)
end_url = url+"?"+data
res = urllib2.Request(end_url)
r = urllib2.urlopen(res)
print r.end_url   #打印url
结果
http://127.0.0.1/decode/ha.php?key_1=value_1&key_2=value_2

设置headers

有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性
import urllib
import urllib2
url = 'http://127.0.0.1/decode/ha.php'
headers = {'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
re = urllib2.Request(url, headers)
r = urllib2.urlopen(re)
print r.read()
我们还有对付”反盗链”的方式,对付防盗链,服务器会识别headers中的referer是不是它自己,如果不是,有的服务器不会响应,所以我们还可以在headers中加入referer
headers = {'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)','Referer':'http://www.zhihu.com/articles'}

Proxy(代理)的设置----其实是设置IP地址(不是太懂)

urllib2 默认会使用环境变量 http_proxy 来设置 HTTP Proxy。假如一个网站它会检测某一段时间某个IP 的访问次数,如果访问次数过多,它会禁止你的访问。所以你可以设置一些代理服务器来帮助你做工作,每隔一段时间换一个代理
import urllib2
enable_proxy = Ture
proxy_handler = urllib2.ProxyHandler({"http":'http://some-proxy.com: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(opener)

Timeout 设置

urlopen()的第三个参数就是timeout
如果第二个参数data为空的话,必须写timeout=……,如果有第二个参数, 那么timeout直接写值就可以了
response = urllib2.urlopen('http://www.baidu.com', timeout=10)
response = urllib2.urlopen('http://www.baidu.com',data, 10)

使用 HTTP 的 PUT 和 DELETE 方法

不常见
import urllib2
request = urllib2.Request(uri, data=data)
request.get_method = lambda: 'PUT'  # or 'DELETE'
response = urllib2.urlopen(request)

添加新评论