python中处理图片常用技巧分析

下面的内容主要介绍了python中处理图片常用技巧,,欢迎大家参考:

本文实例讲述了python使用Image处理图片常用技巧。分享给大家供大家参考。具体分析如下:

使用python来处理图片是非常方便的,下面提供一小段python处理图片的代码,需要安装图像处理工具包PIL(Python Image Library)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#coding=utf-8
import Image
import urllib2
import StringIO
import os
#改变图片大小
def resize_img(img_path):
  try:
    img = Image.open(img_path)
    (width,height) = img.size
    new_width = 200
    new_height = height * new_width / width
    out = img.resize((new_width,new_height),Image.ANTIALIAS)
    ext = os.path.splitext(img_path)[1]
    new_file_name = '%s%s' %('small',ext)
    out.save(new_file_name,quality=95)
  except Exception,e:
    print e
#改变图片类型
def change_img_type(img_path):
  try:
    img = Image.open(img_path)
    img.save('new_type.png')
  except Exception,e:
    print e
#处理远程图片
def handle_remote_img(img_url):
  try:
    request = urllib2.Request(img_url)
    img_data = urllib2.urlopen(request).read()
    img_buffer = StringIO.StringIO(img_data)
    img = Image.open(img_buffer)
    img.save('remote.jpg')
    (width,height) = img.size
    out = img.resize((200,height * 200 / width),Image.ANTIALIAS)
    out.save('remote_small.jpg')
  except Exception,e:
    print e
if __name__ == '__main__':
  img_path = 'test.jpg'
  resize_img(img_path)
  change_img_type(img_path)
  img_url = 'http://img.hb.aicdn.com/042f8a4a70239f724ff7b9fa0fc8edf18658f41022ada-WcItWE_fw554'
  handle_remote_img(img_url)

可能会遇到的问题

ImportError: No module named Image

解决办法:安装Python Imaging Library(PIL)

1
sudo easy_install PIL

安装PIL出现:

— JPEG support not available

— ZLIB (PNG/ZIP) support not available

— FREETYPE2 support not available

操作jpeg图片和png图片出现:

IOError: decoder jpeg not available 和 IOError: encoder zip not available

解决办法:

(1) 删除已经安装的PIL

1
sudo rm -rf /usr/local/lib/python2.6/site-packages/PIL-1.1.7-py2.6-linux-x86_64.egg/

(2) 安装相关库

1
2
3
4
5
6
7
sudo apt-get install libjpeg8 libjpeg62-dev libfreetype6 libfreetype6-dev

sudo ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib/

sudo ln -s /usr/lib/x86_64-linux-gnu/libfreetype.so /usr/lib/

sudo ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/

(3) 重新安装PIL

1
sudo easy_install PIL

终端出现:

— JPEG support available

— ZLIB (PNG/ZIP) support available

— FREETYPE2 support available

现在试试,已经ok了

python中处理图片常用技巧就是这样,欢迎大家参考。。。。

python自动登录人人网并采集信息的实现方法

python自动登录人人网并采集信息是如何来实现的呢?下面的内容将会通过具体的实例来演示python自动登录人人网并采集信息的实现方法及相关技巧:

本文实例讲述了python实现自动登录人人网并采集信息的方法。分享给大家供大家参考。具体实现方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import re
import urllib2
import urllib
import cookielib
class Renren(object):
  def __init__(self):
    self.name = self.pwd = self.content = self.domain = self.origURL = ''
    self.operate = ''#登录进去的操作对象
    self.cj = cookielib.LWPCookieJar()
    try:
      self.cj.revert('./renren.coockie')
    except Exception,e:
      print e
    self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
    urllib2.install_opener(self.opener)
  def setinfo(self,username,password,domain,origURL):
    '''设置用户登录信息'''
    self.name = username
    self.pwd = password
    self.domain = domain
    self.origURL = origURL
  def login(self):
    '''登录人人网'''
    params = {
      'domain':self.domain,
      'origURL':self.origURL,
      'email':self.name,
      'password':self.pwd}
    print 'login.......'
    req = urllib2.Request(
      'http://www.renren.com/PLogin.do',
      urllib.urlencode(params)
    )
    self.file=urllib2.urlopen(req).read()
    newsfeed = open('news.html','w')
    try:
      newsfeed.write(self.file)
    except Exception, e:
      newsfeed.close()
    self.operate = self.opener.open(req)
    print type(self.operate)
    print self.operate.geturl()
    if self.operate.geturl():
      print 'Logged on successfully!'
      self.cj.save('./renren.coockie')
      self.__viewnewinfo()
    else:
      print 'Logged on error'
  def __viewnewinfo(self):
    '''查看好友的更新状态'''
    self.__caiinfo()
  def __caiinfo(self):
    '''采集信息'''
    h3patten = re.compile('<article>(.*&#63;)</article>')#匹配范围
    apatten = re.compile('<h3.+>(.+)</h3>:')#匹配作者
    cpatten = re.compile('</a>(.+)\s')#匹配内容
    content = h3patten.findall(self.file)
    print len(content)
    infocontent = self.operate.readlines()
    print type(infocontent)
    print 'friend newinfo:'
    for i in infocontent:
      content = h3patten.findall(i)
      if len(content) != 0:
        for m in content:
          username = apatten.findall(m)
          info = cpatten.findall(m)
          if len(username) !=0:
            print username[0],'说:',info[0]
            print '----------------------------------------------'
          else:
            continue
ren = Renren()
username = 'username'#你的人人网的帐号
password = 'password'#你的人人网的密码
domain = 'www.renren.com'#人人网的地址
origURL = 'http://www.renren.com/home'#人人网登录以后的地址
ren.setinfo(username,password,domain,origURL)
ren.login()

python自动登录人人网并采集信息就是这样,欢迎大家参考。。。。

Python如何编写爬虫代码采集百度百科页面

本文主要介绍了python中通过对正则表达式的使用来编写爬虫,抓取百度百科页面的方法:

本文实例讲述了python采集百度百科的方法。分享给大家供大家参考。具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/python
# -*- coding: utf-8 -*-
#encoding=utf-8
#Filename:get_baike.py
import urllib2,re
import sys
def getHtml(url,time=10):
 response = urllib2.urlopen(url,timeout=time)
 html = response.read()
 response.close()
 return html
def clearBlank(html):
 if len(html) == 0 : return ''
 html = re.sub('r|n|t','',html)
 while html.find(" ")!=-1 or html.find('&nbsp;')!=-1 :
  html = html.replace('&nbsp;',' ').replace(' ',' ')
 return html
if __name__ == '__main__':
  html = getHtml('http://baike.baidu.com/view/4617031.htm',10)
  html = html.decode('gb2312','replace').encode('utf-8') #转码
  title_reg = r'<h1 class="title" id="[d]+">(.*&#63;)</h1>'
  content_reg = r'<div class="card-summary-content">(.*&#63;)</p>'
  title = re.compile(title_reg).findall(html)
  content = re.compile(content_reg).findall(html)
  title[0] = re.sub(r'<[^>]*&#63;>', '', title[0])
  content[0] = re.sub(r'<[^>]*&#63;>', '', content[0])
  print title[0]
  print '#######################'
  print content[0]

希望本文所述对大家的Python程序设计有所帮助。

python爬虫采集百度百科的方法就是这样,欢迎大家参考。。。。

Python: 『Python』爬行搜索引擎结果获得指定主机所有二级域名

Python: 『Python』爬行搜索引擎结果获得指定主机所有二级域名
Python: 『Python』爬行搜索引擎结果获得指定主机所有二级域名

0x 00 前言

前天自己在玩的时候,自己通过百度搜索主机的二级域名感觉好麻烦,自已要一页页的去翻

而且人工识别是否是重复的二级域名也够蛋疼的,正好最近在学正则表达式,权当练手了

0x 00 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# coding=utf-8
# author:Anka9080
import urllib
import urllib2
import cookielib
import re
url = 'http://www.haosou.com/s?src=360sou_newhome&q=site:tjut.edu.cn&pn=1'
req = urllib2.Request(url)
res = urllib2.urlopen(req)
html = res.read().decode('utf-8')
pageStr = re.search(ur'找到相关结果约(.*?)个',html)
page = pageStr.group(1)
formatNum = '0123456789'
for c in page:
    if not c in formatNum:
       page = page.replace(c,'')
page = int(page) / 10
print page
# 获得搜索结果的页面数
if page > 5:
    page = 5
newItems = []
for p in range(0, page):
    url = 'http://www.haosou.com/s?src=360sou_newhome&q=site:tjut.edu.cn&pn='+'p'
    req = urllib2.Request(url)
    res = urllib2.urlopen(req)
    html = res.read().decode('utf-8')
    pattern = re.compile(r'linkinfo&quot;><cite>(.+?.tjut.edu.cn)')
    items = re.findall(pattern, html)
    # 去重操作
    for item in items:
        if item not in newItems:
            newItems.append(item)
    # 打印去重后的子域名列表
    for item in newItems:
        print item
#print html

测试结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
1330
www.tjut.edu.cn
my.tjut.edu.cn
jw.tjut.edu.cn
jyzx.tjut.edu.cn
lib.tjut.edu.cn
cs.tjut.edu.cn
yjs.tjut.edu.cn
mail.tjut.edu.cn
acm.tjut.edu.cn
www.tjut.edu.cn
my.tjut.edu.cn
jw.tjut.edu.cn
jyzx.tjut.edu.cn
lib.tjut.edu.cn
cs.tjut.edu.cn
yjs.tjut.edu.cn
mail.tjut.edu.cn
acm.tjut.edu.cn
www.tjut.edu.cn
my.tjut.edu.cn
jw.tjut.edu.cn
jyzx.tjut.edu.cn
lib.tjut.edu.cn
cs.tjut.edu.cn
yjs.tjut.edu.cn
mail.tjut.edu.cn
acm.tjut.edu.cn
www.tjut.edu.cn
my.tjut.edu.cn
jw.tjut.edu.cn
jyzx.tjut.edu.cn
lib.tjut.edu.cn
cs.tjut.edu.cn
yjs.tjut.edu.cn
mail.tjut.edu.cn
acm.tjut.edu.cn
www.tjut.edu.cn
my.tjut.edu.cn
jw.tjut.edu.cn
jyzx.tjut.edu.cn
lib.tjut.edu.cn
cs.tjut.edu.cn
yjs.tjut.edu.cn
mail.tjut.edu.cn
acm.tjut.edu.cn

0x 02 总结

思路大概是这个样子:

先通过 urllib2.Request() 和 urllib2.urlopen() 访问url

再从返回结果中得到搜索结果页面数 

为了提高效率 页面数 大于 5 会只爬行搜索结果的前5个页面

后面 又做了去重操作 然后就得到二级域名列表咯 : )

中间蛋疼的 地方倒是 Py 的 转义符号问题  身边能有个可以问问的大牛多好~

后期 准备使用  http://dns.aizhan.com/ 的查询结果 直接获得 IP以及旁站信息

文中图片引自:http://developer.51cto.com/art/201403/431104.htm(原博客链接失效)

原文:http://www.cnblogs.com/anka9080/p/getsubdomain.html

Python: 【Python爬虫实战】爬取糗事百科段子

来自: 静觅丨崔庆才的个人博客

链接:http://cuiqingcai.com/990.html

声明:本文仅限技术交流讨论

这次为大家带来,Python爬取糗事百科的小段子的例子。

首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来。

本篇目标

1.抓取糗事百科热门段子

2.过滤带有图片的段子

3.实现每按一次回车显示一个段子的发布时间,发布人,段子内容,点赞数。

糗事百科是不需要登录的,所以也没必要用到Cookie,另外糗事百科有的段子是附图的,我们把图抓下来图片不便于显示,那么我们就尝试过滤掉有图的段子吧。

好,现在我们尝试抓取一下糗事百科的热门段子吧,每按下一次回车我们显示一个段子。

1 . 确定URL并抓取页面代码

首先我们确定好页面的URL是 http://www.qiushibaike.com/hot/page/1,其中最后一个数字1代表页数,我们可以传入不同的值来获得某一页的段子内容。

我们初步构建如下的代码来打印页面代码内容试试看,先构造最基本的页面抓取方式,看看会不会成功

# -*- coding:utf-8 -*-

import urllib

import urllib2

page = 1

url = ‘http://www.qiushibaike.com/hot/page/’ + str(page)

try:

request = urllib2.Request(url)

response = urllib2.urlopen(request)

print response.read()

except urllib2.URLError, e:

if hasattr(e,”code>”):

print e.code

if hasattr(e,”reason>”):

print e.reason

运行程序,哦不,它竟然报错了,真是时运不济,命途多舛啊

line 373, in _read_status

raise BadStatusLine(line)

httplib.BadStatusLine: ”

好吧,应该是headers验证的问题,我们加上一个headers验证试试看吧,将代码修改如下

# -*- coding:utf-8 -*-

import urllib

import urllib2

page = 1

url = ‘http://www.qiushibaike.com/hot/page/’ + str(page)

user_agent = ‘Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)’

headers = { ‘User-Agent’ : user_agent }

try:

request = urllib2.Request(url,headers = headers)

response = urllib2.urlopen(request)

print response.read()

except urllib2.URLError, e:

if hasattr(e,”code>”):

print e.code

if hasattr(e,”reason>”):

print e.reason

嘿嘿,这次运行终于正常了,打印出了第一页的HTML代码,大家可以运行下代码试试看。在这里运行结果太长就不贴了。

2.提取某一页的所有段子

好,获取了HTML代码之后,我们开始分析怎样获取某一页的所有段子。

首先我们审查元素看一下,按浏览器的F12,截图如下

我们可以看到,每一个段子都是

包裹的内容。

现在我们想获取发布人,发布日期,段子内容,以及点赞的个数。不过另外注意的是,段子有些是带图片的,如果我们想在控制台显示图片是不现实的,所以我们直接把带有图片的段子给它剔除掉,只保存仅含文本的段子。

所以我们加入如下正则表达式来匹配一下,用到的方法是 re.findall 是找寻所有匹配的内容。方法的用法详情可以看前面说的正则表达式的介绍。

好,我们的正则表达式匹配语句书写如下,在原来的基础上追加如下代码

content = response.read().decode(‘utf-8’)

pattern = re.compile(‘.*?.*?(.*?).*?

‘=>”content”.*?title=>”(.*?)”>(.*?)

(.*?)

“stats.*?class=”number>”>(.*?)‘,re.S)

items = re.findall(pattern,content)

for item in items:

print item[0],item[1],item[2],item[3],item[4]

现在正则表达式在这里稍作说明

1).*? 是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。

2)(.*?)代表一个分组,在这个正则表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.*?)所指代的内容,item[1]就代表第二个(.*?)所指代的内容,以此类推。

3)re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。

现在我们可以看一下部分运行结果

儒雅男神 2015-02-17 14:34:42

小时候一个一个拆着放的举个爪…

7093

奇怪的名字啊 2015-02-17 14:49:16

回家的路,你追我赶,回家的心情和窗外的阳光一样灿烂。一路向前,离亲人越来越近了。哪里有爸妈哪里才是家,希望所有糗友的爸爸妈妈都身体健康…….

4803

这是其中的两个段子,分别打印了发布人,发布时间,发布内容,附加图片以及点赞数。

其中,附加图片的内容我把图片代码整体抠了出来,这个对应item[3],所以我们只需要进一步判断item[3]里面是否含有img这个字样就可以进行过滤了。

好,我们再把上述代码中的for循环改为下面的样子

for item in items:

haveImg = re.search(“img>”,item[3])

if not haveImg:

print item[0],item[1],item[2],item[4]

现在,整体的代码如下

# -*- coding:utf-8 -*-

import urllib

import urllib2

import re

page = 1

url = ‘http://www.qiushibaike.com/hot/page/’ + str(page)

user_agent = ‘Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)’

headers = { ‘User-Agent’ : user_agent }

try:

request = urllib2.Request(url,headers = headers)

response = urllib2.urlopen(request)

content = response.read().decode(‘utf-8’)

pattern = re.compile(‘.*?.*?(.*?).*?

‘=>”content”.*?title=>”(.*?)”>(.*?)

(.*?)

“stats.*?class=”number>”>(.*?)‘,re.S)

items = re.findall(pattern,content)

for item in items:

haveImg = re.search(“img>”,item[3])

if not haveImg:

print item[0],item[1],item[2],item[4]

except urllib2.URLError, e:

if hasattr(e,”code>”):

print e.code

if hasattr(e,”reason>”):

print e.reason

运行一下看下效果

恩,带有图片的段子已经被剔除啦。是不是很开森?

3.完善交互,设计面向对象模式

好啦,现在最核心的部分我们已经完成啦,剩下的就是修一下边边角角的东西,我们想达到的目的是:

按下回车,读取一个段子,显示出段子的发布人,发布日期,内容以及点赞个数。

另外我们需要设计面向对象模式,引入类和方法,将代码做一下优化和封装,最后,我们的代码如下所示

__author__ = ‘CQC’

# -*- coding:utf-8 -*-

import urllib

import urllib2

import re

import thread

import time

#糗事百科爬虫类

class QSBK:

#初始化方法,定义一些变量

def __init__(self):

self.pageIndex = 1

self.user_agent = ‘Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)’

#初始化headers

self.headers = { ‘User-Agent’ : self.user_agent }

#存放段子的变量,每一个元素是每一页的段子们

self.stories = []

#存放程序是否继续运行的变量

self.enable = False

#传入某一页的索引获得页面代码

def getPage(self,pageIndex):

try:

url = ‘http://www.qiushibaike.com/hot/page/’ + str(pageIndex)

#构建请求的request

request = urllib2.Request(url,headers = self.headers)

#利用urlopen获取页面代码

response = urllib2.urlopen(request)

#将页面转化为UTF-8编码

pageCode = response.read().decode(‘utf-8’)

return pageCode

except urllib2.URLError, e:

if hasattr(e,”reason>”):

print u”连接糗事百科失败,错误原因>”,e.reason

return None

#传入某一页代码,返回本页不带图片的段子列表

def getPageItems(self,pageIndex):

pageCode = self.getPage(pageIndex)

if not pageCode:

print “页面加载失败….>”

return None

pattern = re.compile(‘.*?.*?(.*?).*?

‘=>”content”.*?title=>”(.*?)”>(.*?)

(.*?)

“stats.*?class=”number>”>(.*?)‘,re.S)

items = re.findall(pattern,pageCode)

#用来存储每页的段子们

pageStories = []

#遍历正则表达式匹配的信息

for item in items:

#是否含有图片

haveImg = re.search(“img>”,item[3])

#如果不含有图片,把它加入list中

if not haveImg:

#item[0]是一个段子的发布者,item[1]是发布时间,item[2]是内容,item[4]是点赞数

pageStories.append([item[0].strip(),item[1].strip(),item[2].strip(),item[4].strip()])

return pageStories

#加载并提取页面的内容,加入到列表中

def loadPage(self):

#如果当前未看的页数少于2页,则加载新一页

if self.enable == True:

if len(self.stories) < 2:

#获取新一页

pageStories = self.getPageItems(self.pageIndex)

#将该页的段子存放到全局list中

if pageStories:

self.stories.append(pageStories)

#获取完之后页码索引加一,表示下次读取下一页

self.pageIndex += 1

#调用该方法,每次敲回车打印输出一个段子

def getOneStory(self,pageStories,page):

#遍历一页的段子

for story in pageStories:

#等待用户输入

input = raw_input()

#每当输入回车一次,判断一下是否要加载新页面

self.loadPage()

#如果输入Q则程序结束

if input == “Q>”:

self.enable = False

return

print u”第%d页\t发布人:%s\t发布时间:%s\n%s\n赞:%s\n>” %(page,story[0],story[1],story[2],story[3])

#开始方法

def start(self):

print u”正在读取糗事百科,按回车查看新段子,Q退出>”

#使变量为True,程序可以正常运行

self.enable = True

#先加载一页内容

self.loadPage()

#局部变量,控制当前读到了第几页

nowPage = 0

while self.enable:

if len(self.stories)>0:

#从全局list中获取一页的段子

pageStories = self.stories[0]

#当前读到的页数加一

nowPage += 1

#将全局list中第一个元素删除,因为已经取出

del self.stories[0]

#输出该页的段子

self.getOneStory(pageStories,nowPage)

spider = QSBK()

spider.start()

好啦,大家来测试一下吧,点一下回车会输出一个段子,包括发布人,发布时间,段子内容以及点赞数,是不是感觉爽爆了!

我们第一个爬虫实战项目介绍到这里,欢迎大家继续关注,小伙伴们加油!

来自: 静觅丨崔庆才的个人博客

链接:http://cuiqingcai.com/990.html

荐号:IT创业网

互联网创业的时代,创业更具人文气息。聚最经典的IT创业技巧,最顶尖的商界精英交流平台。

微信号: chuangyetech

↑↑↑长摁二维码试试

●本文编号856,以后想阅读这篇文章直接输入856即可。

●本文分类“ 搜索引擎技术 ”,搜索分类名可以获得相关文章。

●输入m可以获取到全部文章目录

●输入r可以获取到热门文章推荐

●输入f可以获取到全部分类名称

原文:http://mp.weixin.qq.com/s?__biz=MjM5NzA1MTcyMA==&mid=206571806&idx=5&sn=59a2ddfac1da6804345538c16d01c661&3rd=MzA3MDU4NTYzMw==&scene=6#rd

Python 标准库 urllib2 的使用细节

Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库。这里总结了一些 urllib2 库的使用细节。

1 Proxy 的设置

2 Timeout 设置

3 在 HTTP Request 中加入特定的 Header

4 Redirect

5 Cookie

6 使用 HTTP 的 PUT 和 DELETE 方法

7 得到 HTTP 的返回码

8 Debug Log

1 Proxy 的设置

urllib2 默认会使用环境变量 http_proxy 来设置 HTTP Proxy。如果想在程序中明确控制 Proxy,而不受环境变量的影响,可以使用下面的方式。

1
2
3
4
5
6
7
8
9
10
11
12
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)

这里要注意的一个细节,使用 urllib2.install_opener() 会设置 urllib2 的全局 opener。这样后面的使用会很方便,但不能做更细粒度的控制,比如想在程序中使用两个不同的 Proxy 设置等。比较好的做法是不使用 install_opener 去更改全局的设置,而只是直接调用 opener 的 open 方法代替全局的 urlopen 方法。
2 Timeout 设置

在老版本中,urllib2 的 API 并没有暴露 Timeout 的设置,要设置 Timeout 值,只能更改 Socket 的全局 Timeout 值。

1
2
3
4
5
import urllib2
import socket

socket.setdefaulttimeout(10) # 10 秒钟后超时
urllib2.socket.setdefaulttimeout(10) # 另一种方式

3 在 HTTP Request 中加入特定的 Header

要加入 Header,需要使用 Request 对象:

1
2
3
4
5
import urllib2

request = urllib2.Request(uri)
request.add_header('User-Agent', 'fake-client')
response = urllib2.urlopen(request)

对有些 header 要特别留意,Server 端会针对这些 header 做检查

User-Agent 有些 Server 或 Proxy 会检查该值,用来判断是否是浏览器发起的 Request

Content-Type 在使用 REST 接口时,Server 会检查该值,用来确定 HTTP Body 中的内容该怎样解析。

常见的取值有:

在使用 RPC 调用 Server 提供的 RESTful 或 SOAP 服务时, Content-Type 设置错误会导致 Server 拒绝服务。

application/xml :在 XML RPC,如 RESTful/SOAP 调用时使用

application/json :在 JSON RPC 调用时使用

application/x-www-form-urlencoded :浏览器提交 Web 表单时使用

……

4 Redirect

urllib2 默认情况下会针对 3xx HTTP 返回码自动进行 Redirect 动作,无需人工配置。要检测是否发生了 Redirect 动作,只要检查一下 Response 的 URL 和 Request 的 URL 是否一致就可以了。

1
2
import urllib2
response = urllib2.urlopen('http://www.google.cn')redirected = response.geturl() == 'http://www.google.cn'

如果不想自动 Redirect,除了使用更低层次的 httplib 库之外,还可以使用自定义的 HTTPRedirectHandler 类。

1
2
3
4
5
6
7
8
9
10
11
import urllib2

class RedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_301(self, req, fp, code, msg, headers):
        pass
    def http_error_302(self, req, fp, code, msg, headers):
        pass

opener = urllib2.build_opener(RedirectHandler)
opener.open('http://www.google.cn')
5 Cookie

urllib2 对 Cookie 的处理也是自动的。如果需要得到某个 Cookie 项的值,可以这么做:

1
2
3
4
5
6
7
8
9
import urllib2
import cookielib

cookie = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
response = opener.open('http://www.google.com')
for item in cookie:
    if item.name == 'some_cookie_item_name':
        print item.value

6 使用 HTTP 的 PUT 和 DELETE 方法

1
2
3
4
5
import urllib2

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

7 得到 HTTP 的返回码

对于 200 OK 来说,只要使用 urlopen 返回的 response 对象的 getcode() 方法就可以得到 HTTP 的返回码。但对其它返回码来说,urlopen 会抛出异常。这时候,就要检查异常对象的 code 属性了:

1
2
3
4
5
6
import urllib2
try:
    response = urllib2.urlopen('http://restrict.web.com')
except urllib2.HTTPError, e:
    print e.code
8 Debug Log

使用 urllib2 时,可以通过下面的方法把 Debug Log 打开,这样收发包的内容就会在屏幕上打印出来,方便我们调试,在一定程度上可以省去抓包的工作。

1
2
3
4
5
6
7
8
import urllib2

httpHandler = urllib2.HTTPHandler(debuglevel=1)
httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
opener = urllib2.build_opener(httpHandler, httpsHandler)

urllib2.install_opener(opener)
response = urllib2.urlopen('http://www.google.com')

来源:http://linuxadmin.blog.51cto.com/2683824/1610811