爬虫入门-02 urllib库的使用 和简单的 cookie使用

urllib库的使用:

  urlopen()接受三个参数,urlopen(url,data=None,timeout=socket._GLOBAL_DEFAULT_TIMEOUT) ,data是访问url时要传送的数据,返回一个response对象,response对象中有一个read方法,可以返回获取到的网页内容

import urllib
url = 'https://www.baidu.com/index.php?tn=monline_3_dg'
print urllib.urlopen(url)
print urllib.urlopen(url).read()

结果如下:

<addinfourl at 85341256L whose fp = <socket._fileobject object at 0x0000000005167A20>>
<html>
<head>
    <script>
        location.replace(location.href.replace("https://","http://"));
    </script>
</head>
<body>
    <noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>

可知不加read打印出来的是该对象的描述,加了read打印出来是网页的html代码

  urlretrieve () 直接将远程数据下载到本地。 urllib.urlretrieve(url[, filename[, reporthook[, data]]])
参数说明:
url:外部或者本地url
filename:指定了保存到本地的路径(如果未指定该参数,urllib会生成一个临时文件来保存数据);
reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。我们可以利用这个回调函数来显示当前的下载进度。
data:指post到服务器的数据。该方法返回一个包含两个元素的元组(filename, headers),filename表示保存到本地的路径,header表示服务器的响应头。

一个小小的例子,还有待改进,爬取豆瓣读书的页面图片,下载并保存到本地:

# coding=utf-8
import urllib
import re import requests import sys reload(sys) sys.setdefaultencoding('utf8') url = 'https://book.douban.com/' headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/59.0"} data = requests.get(url,headers=headers).text pat = re.compile('<div class="cover">.*?<img\ssrc="(.*?)".*?alt="(.*?)".*?>',re.S) res = re.findall(pat,data) for i in res: path = 'G:\image\%s.jpg' % str(i[1]).decode('utf-8').encode('gbk', 'ignore') urllib.urlretrieve(i[0],path) print i

 有些图片并不能被找到,正则表达式真难写

构造request:

import urllib2
url = 'https://www.baidu.com/index.php?tn=monline_3_dg'
request = urllib2.Request(url = 'https://www.baidu.com/index.php?tn=monline_3_dg')
response = urllib2.urlopen(request)
print response.read()

结果同上,都是打印html代码,这样写显得逻辑清晰,可读性更好。

POST和GET数据传送: 

import urllib
import urllib2

values = {"username":"1016903103@qq.com","password":"XXXX"}
data = urllib.urlencode(values) 
url = "https://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()

  GET方式我们可以直接把参数写到url上

import urllib
import urllib2

values={}
values['username'] = "1016903103@qq.com"
values['password']="XXXX"
data = urllib.urlencode(values) 
url = "http://passport.csdn.net/account/login"
geturl = url + "?"+data
request = urllib2.Request(geturl)
response = urllib2.urlopen(request)
print response.read()
print geturl

 一些增强爬虫可行性的方法:

 1、封装请求头Header

  有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性

Header的一些属性:
User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求 Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。 application/xml : 在 XML RPC,如 RESTful/SOAP 调用时使用 application/json : 在 JSON RPC 调用时使用 application/x-www-form-urlencoded : 浏览器提交 Web 表单时使用 在使用服务器提供的 RESTful 或 SOAP 服务时, Content-Type 设置错误会导致服务器拒绝服务
import urllib  
import urllib2  

url = 'http://www.server.com/login'
user_agent = 'Mozilla/4.0 (compatible; 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(request)  
page = response.read() 

还可以增加一个Referer属性,服务器识别Referer是不是自己

headers = { 'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'  ,
                        'Referer':'http://www.zhihu.com/articles' }  

2、Proxy代理设置

  一些服务器会检测某个IP在一段时间内访问服务器的次数,次数多了可能会被封,所以你可以设置一些代理服务器来帮助你做工作,每隔一段时间换一个代理

# import urllib2
# enable_proxy = True
# 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)

URLError异常处理:

  try-except语句来包围并捕获相应的异常

  1、URLError异常,可能原因:没联网;连接不到特定的服务器;服务器不存在

import urllib2

requset = urllib2.Request('http://www.xxxxx.com')
try:
    urllib2.urlopen(request)
except urllib2.URLError, e:
    print e.reason
[Errno 11004] getaddrinfo failed

  以上是预期结果,但我运行时输出的是空,debug不出来,我就留着一会儿再解决吧

  2、HTTOError异常

  是URLError的一个子类,利用urlopen发出请求时,会得到一个response,其中包含一个数字状态码,如下

    100:继续  客户端应当继续发送请求。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。

    101: 转换协议  在发送完这个响应最后的空行后,服务器将会切换到在Upgrade 消息头中定义的那些协议。只有在切换新的协议更有好处的时候才应该采取类似措施。

    102:继续处理   由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。

    200:请求成功      处理方式:获得响应的内容,进行处理

    201:请求完成,结果是创建了新资源。新创建资源的URI可在响应的实体中得到    处理方式:爬虫中不会遇到

    202:请求被接受,但处理尚未完成    处理方式:阻塞等待

    204:服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。    处理方式:丢弃
300:该状态码不被HTTP/1.0的应用程序直接使用, 只是作为3XX类型回应的默认解释。存在多个可用的被请求资源。 处理方式:若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃
301:请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源 处理方式:重定向到分配的URL 302:请求到的资源在一个不同的URL处临时保存 处理方式:重定向到临时的URL 304:请求的资源未更新 处理方式:丢弃 400:非法请求 处理方式:丢弃 401:未授权 处理方式:丢弃 403:禁止 处理方式:丢弃 404:没有找到 处理方式:丢弃 500:服务器内部错误 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。 501:服务器无法识别 服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。 502:错误网关 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。 503:服务出错 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。

  HTTPError产生后会有一个code属性,就是上面的服务器发送的错误数字状态码

import urllib2

req = urllib2.Request('http://blog.csdn.net/cqcre')
try:
    urllib2.urlopen(req)
except urllib2.HTTPError, e:
    print e.code
    print e.reason

  预期结果,反正我的还是空,然后我发现了python中的traceback模块,该模块用于捕获并打印异常

try:
    1/0
except Exception,e:
    traceback.print_exc()
# Traceback (most recent call last):
#   File "D:/PyCharm Community Edition 2017.1.5/PycharmProjects/Learning-01/learn-01.py", line 75, in <module>
#     1/0
# ZeroDivisionError: integer division or modulo by zero

  然而还是并没有什么用,得不到预期结果

403
Forbidden

 Cookie的使用:

  1、保存cookie到变量

# import urllib2
# import cookielib
# #声明一个cookiejar对象实例来保存cookie
# cookie = cookielib.CookieJar()
# #创建cookie处理器
# handler = urllib2.HTTPCookieProcessor(cookie)
# #构建opener
# opener = urllib2.build_opener(handler)
# #传入request
# response = opener.open('http://www.baidu.com')
# for item in cookie:
#     print 'Name = ',item.name
#     print 'Value = ',item.value
Name = BAIDUID
Value = B07B663B645729F11F659C02AAE65B4C:FG=1
Name = BAIDUPSID
Value = B07B663B645729F11F659C02AAE65B4C
Name = H_PS_PSSID
Value = 12527_11076_1438_10633
Name = BDSVRTM
Value = 0
Name = BD_HOME
Value = 0

  2、保存cookie到本地

filename = 'cookie.txt'
#声明一个MozillaCookieJar对象实例来保存cookie,之后写入文件
'''
    This class differs from CookieJar only in the format it uses to save and
    load cookies to and from a file.  This class uses the Mozilla/Netscape
    `cookies.txt' format.
'''
cookie = cookielib.MozillaCookieJar(filename)
#利用urllib2库的HTTPCookieProcessor对象来创建cookie处理器
handler = urllib2.HTTPCookieProcessor(cookie)
#通过handler来构建opener
opener = urllib2.build_opener(handler)
#创建一个请求,原理同urllib2的urlopen
response = opener.open("http://www.baidu.com")
#保存cookie到文件
cookie.save(ignore_discard=True, ignore_expires=True)

  cookie.txt中的内容

# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file!  Do not edit.

.baidu.com    TRUE    /    FALSE    3669689570    BAIDUID    F22129FBCD4334DCB6A4DD8AE95E03DC:FG=1
.baidu.com    TRUE    /    FALSE    3669689570    BIDUPSID    F22129FBCD4334DCB6A4DD8AE95E03DC
.baidu.com    TRUE    /    FALSE        H_PS_PSSID    1425_21118
.baidu.com    TRUE    /    FALSE    3669689570    PSTM    1522205924
www.baidu.com    FALSE    /    FALSE        BDSVRTM    0
www.baidu.com    FALSE    /    FALSE        BD_HOME    0

  3、从文件中获取cookie并访问

# import cookielib
# import urllib2
# cookie = cookielib.MozillaCookieJar()
# cookie.load('cookie.txt',ignore_discard=True,ignore_expires=True)
# opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
# req = urllib2.Request('http://www.baidu.com')
# response = opener.open(req)
# print response.read()

  4、利用cookie模拟网站登录

import urllib
import urllib2
import cookielib
filename = 'cookie.txt'
cookie = cookielib.MozillaCookieJar(filename)
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
#输入你自己的账号
postdata = urllib.urlencode({'id':'xxxx','pwd':'xxxx'})
loginurl = 'https://www.zhihu.com/signup?next=%2F'
result = opener.open(loginurl,data=postdata)
cookie.save(ignore_expires=True,ignore_discard=True)
#打开编辑个人信息的页面
inputurl = 'https://www.zhihu.com/people/edit'
response = opener.open(inputurl)
print response.read()

  结果如下,讲道理,我没想到这么长的- 。 -

<!doctype html>
<html lang="zh" data-hairline="true" data-theme="light"><head><meta chars 。。。。后面太长了我就不粘了

 

转载于:https://www.cnblogs.com/WXfresh/p/8658151.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值