博客是我工作的好帮手,遇到困难就来博客找资料
分类: 系统运维
2017-03-29 17:04:47
python urllib.request之urlopen函数
urllib是基于http的高层库,它有以下三个主要功能:
(1)request处理客户端的请求
(2)response处理服务端的响应
(3)parse会解析url
下面讨论的是request
urllib.request模块定义了一些打开URLs(一般是HTTP协议)复杂操作像是basic 和摘要模式认证,重定向,cookies等的方法和类。这个模块式模拟文件模块实现的,将本地的文件路径改为远程的url。因此函数返回的是类文件对象(file-like object)
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
url可以是一个字符串形式或者Request 对象
如果data参数有值就是用post方式响应否则默认为GET 方式
urllib.request 模块使用HTTP/1.1 的无连接的状态协议
urlopen()函数返回类文件对象,提供以下内建方法:
- read() , readline() ,readlines() , fileno() , close() :这些方法的使用方式与文件对象完全一样
- info():返回一个httplib.HTTPMessage对象,表示远程服务器返回的头信息
- getcode():返回Http状态码。(详情参考)
如果是http请求:
1xx(informational):请求已经收到,正在进行中
2xx(successful):请求成功接收,解析,完成
3xx(Redirection):需要重定向
4xx(Client Error):客户端问题,请求存在语法错误,网址未找到
5xx(Server Error):服务器问题
- geturl():返回请求的url
#!/opt/yrd_soft/bin/python
import re
import urllib2
import requests
import lxml
from bs4 import BeautifulSoup
url = ''
#page=urllib2.urlopen(url)
page=requests.get(url).text
pagesoup=BeautifulSoup(page,'lxml')
for link in pagesoup.find_all(name='a',attrs={"href":re.compile(r'^http:')}):
print link.get_text()
通过BeautifulSoup库的get_text方法找到网页的正文:
#!/usr/bin/env python
#coding=utf-8
#HTML找出正文
import requests
from bs4 import BeautifulSoup
url=''
html=requests.get(url)
soup=BeautifulSoup(html.text)
print soup.get_text()
1 urllib2 简介
urllib2是python自带的一个访问网页及本地文件的库。
与urllib相比,显著区别之处在于:
1) urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。这意味着,用urllib时不可以伪装User Agent字符串等。
2) urllib提供urlencode方法用来encode发送的data,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。
2 urllib2 常用方法
2.1 urllib2.urlopen
urlopen()是最简单的请求方式,它打开url并返回类文件对象,并且使用该对象可以读取返回的内容
urllib2.urlopen(url[, data][, timeout])
参数:
url: 可以是包含url的字符串,也可以是urllib2.request类的实例。
data: 是经过编码的post数据(一般使用urllib.urlencode()来编码)。
没有data参数时为GET请求,设置data参数时为POST请求
timeout: 是可选的超时期(以秒为单位),设置请求阻塞的超时时间,如果没有设置的话,会使用全局默认timeout参数,该参数只对HTTP、HTTPS、FTP生效
假设urlopen()返回的文件对象u,它支持下面的这些常用的方法:
u.read([nbytes]) 以字节字符串形式读取nbytes个数据
u.readline() 以字节字符串形式读取单行文本
u.readlines() 读取所有输入行然后返回一个列表
u.close() 关闭链接
u.getcode() 返回整数形式的HTTP响应代码,比如成功返回200,未找到文件时返回404
u.geturl() 返回所返回的数据的实际url,但是会考虑发生的重定向问题
u.info() 返回映射对象,该对象带有与url关联的信息。
对HTTP来说,返回的服务器响应包含HTTP包头。
对于FTP来说,返回的报头包含'content-length'。
对于本地文件,返回的报头包含‘content-length’和'content-type'字段。
注意:
类文件对象u以二进制模式操作。如果需要以文本形式处理响应数据,则需要使用codecs模块或类似
方式解码数据。
附代码:
>>> import urllib2
>>> res=urllib2.urlopen('')
>>>res.read()
。。。。。。(一堆源代码)
>>>res.readline()
' Transitional//EN""">\r\n'
>>>res.readlines()
。。。(list形式的一堆源码)
>>>res.info()
>>>res.getcode()
200
>>>res.geturl()
''
#最后关闭连接
>>> res.close()
2.2 urllib2.request
新建Request实例
Request (url [data,headers[,origin_req_host ,[unverifiable]]]])
说明:
对于比较简单的请求,urlopen()的参数url就是一个代表url的,但如果需要执行更复杂的操作,如修改HTTP报头,可以创建Request实例并将其作为url参数
参数:
url: 为url字符串,
data: 是伴随url提交的数据(比如要post的数据)。不过要注意,提供data参数时,它会将HTTP请求从'GET'改为‘POST’。
headers: 是一个字典,包含了可表示HTTP报头的键值映射(即要提交的header中包含的内容)。
origin_req_host: 通常是发出请求的主机的名称,如果请求的是无法验证的url(通常是指不是用户直接输入的url,比如加载图像的页面中镶入的url),则后一个参数unverifiable设为TRUE
假设Request实例r,其比较重要的方法有下面几个:
r.add_data(data) 向请求添加数据。如果请求是HTTP请求,则方法改为‘POST’。
data是向指定url提交的数据,要注意该方法不会将data追教导之前已经设置的任何数据上,而是使用现在的data替换之前的。
r.add_header(key, val) 向请求添加header信息,key是报头名,val是报头值,两个参数都是字符串。
r.addunredirectedheader(key,val) 作用基本同上,但不会添加到重定向请求中。
r.set_proxy(host, type) 准备请求到服务器。使用host替换原来的主机,使用type替换原来的请求类型。
附代码:
1 向网页提交数据:
>>> import urllib
>>> import urllib2
>>> url=''
>>> info={'name':"51cto",'location':'51cto'}
#info需要被编码为urllib2能理解的格式,这里用到的是urllib
>>> data=urllib.urlencode(info)
>>> data
'name=51cto&location=51cto'
>>> request=urllib2.Request(url,data)
>>> response=urllib2.urlopen(request)
>>> the_page=response.read()
2 修改网页头信息:
有时会碰到,程序也对,但是服务器拒绝你的访问。这是为什么呢?问题出在请求中的头信息(header)。 有的服务端有洁癖,不喜欢程序来触摸它。这个时候你需要将你的程序伪装成浏览器来发出请求。请求的方式就包含在header中。
在使用 REST 接口时,Server 会检查Content-Type字段,用来确定 HTTP Body 中的内容该怎样解析。
>>> import urllib
>>> import urllib2
>>> url=''
# 将user_agent写入头信息
>>> user_agent='Mozilla/4.0 (compatible; MSIE 5.5; WindowsNT)'
>>>values={'name':'51cto','location':"51cto",'language':'Python'}
>>> headers={'User-Agent':user_agent}
>>> data=urllib.urlencode(values)
>>> req=urllib2.Request(url,data,headers)
>>> response=urllib2.urlopen(req)
>>> the_page=response.read()
2.3 异常处理
不能处理一个respons时,urlopen抛出一个urlerror
urllib2.URLError:
urllib2.HTTPError:
HTTPerror是HTTP URL在特别的情况下被抛出的URLError的一个子类。
urlerror:
通常,urlerror被抛出是因为没有网络 连接(没有至特定服务器的连接)或者特定的服务器不存在。在这种情况下,含有reason属性的异常将被抛出,以一种包含错误代码 和文本错误信息的tuple形式。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib2
#多写了一个 m (comm)
req = urllib2.Request('m')
try:
urllib2.urlopen(req)
except urllib2.URLError,e:
print e
print e.reason
结果:
python之web模块学习,基本上涉及常用的的web模块,包括 urllib、urllib2、httplib、urlparse、requests,现在,开始我们的第一个模块的学习吧。
1 urllib简介
python urllib 模块提供了一个从指定的URL地址获取网页数据,然后对其进行分析处理,获取我们想要的数据。
2 常用方法
2.1 urlopen -- 创建一个类文件对象 为读取指定的URL
help(urllib.urlopen)
urlopen(url, data=None, proxies=None)
Create a file-like object for the specified URL to read from.
参数:
url :表示远程数据的路径,一般是http或者ftp路径。
data :表示以get或者post方式提交到url的数据。
proxies :表示用于代理的设置。
Python 通过urlopen函数来获取html数据,urlopen返回一个类文件对象,它提供了如下常用方法:
1)read() , readline() , readlines(),fileno()和close():这些方法的使用与文件对象完全一样。
2)info():返回一个httplib.HTTPMessage 对象,表示远程服务器返回的头信息。
3)getcode():返回Http状态码,如果是http请求,200表示请求成功完成;404表示网址未找到。
4)geturl():返回请求的url地址。
附代码:
>>> import urllib
>>> response = urllib.urlopen('')
>>>res.read()
。。。。。。(一堆网页代码)
>>>res.readline()
'\r\n'
。。。。
>>>res.readlines()
。。。(list形式的一堆网页代码)
>>>res.info()
>>> response.getcode() # 返回Http状态码
200
>>> response.geturl() # 返回请求的url地址
''
>>> response.close() # 最后别忘了关闭连接
urllib中还提供了一些辅助方法,用于对url进行编码、解码。url中是不能出现一些特殊的符号的,有些符号有特殊的用途。我们知道以get方式提交数据的时候,会在url中添加key=value这样的字符串,所以在value中是不允许有'=',因此要对其进行编码;与此同时服务器接收到这些参数的时候,要进行解码,还原成原始的数据。这个时候,这些辅助方法会很有用:
附带的其他方法:(主要是url编码解码)
- urllib.quote(string[, safe]):对字符串进行编码。参数safe指定了不需要编码的字符
- urllib.unquote(string) :对字符串进行解码
- urllib.quote_plus(string [ , safe ] ) :与urllib.quote类似,但这个方法用'+'来替换' ',而quote用'%20'来代替' '
- urllib.unquote_plus(string ) :对字符串进行解码
- urllib.urlencode(query[, doseq]):将dict或者包含两个元素的元组列表转换成url参数。例如 字典{'name': 'wklken', 'pwd':'123'}将被转换为"name=wklken&pwd=123" (常用)
#这里可以与urlopen结合以实现post方法和get方法
- urllib.pathname2url(path):将本地路径转换成url路径
- urllib.url2pathname(path):将url路径转换成本地路径
附代码:
>>> import urllib
>>>res = urllib.quote('I am 51cto')
>>> res
'I%20am%2051cto'
>>>urllib.unquote(res)
'I am 51cto'
>>>res = urllib.quote_plus('I am 51cto')
>>> res
'I+am+51cto'
>>>urllib.unquote_plus(res)
'I am 51cto'
>>> params = {'name':'51cto','pwd':'51cto'}
>>>urllib.urlencode(params)
'pwd=51cto&name=51cto'
>>>l2u=urllib.pathname2url('E:\51cto')
'E%3A%29cto'
>>>urllib.url2pathname(l2u)
'E:)cto'
2.2 urlretrieve -- 直接将远程的数据下载到本地
help(urllib.urlretrieve)
urlretrieve(url, filename=None,reporthook=None, data=None)
参数:
url :指定下载的URL
finename :指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。
reporthook :是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。
data: 表示post到服务器的数据,该方法返回一个包含两个元素的(filename,headers)元组,
下面是一个 urlretrieve方法下载文件的实例,可以显示下载进度:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib
import os
def schedule(a,b,c):
''' 回调函数
@a:已经下载的数据
@b:数据块的大小
@c:远程文件的大小
'''
per = 100.0 * a * b / c
if per > 100:
per = 100
print "%.2f%%" % per
url = ''
local = os.path.join('c:','Python-2.7.5.tar.bz2')
urllib.urlretrieve(url,local,schedule)
2.3 urlcleanup -- 清除由于urllib.urlretrieve()所产生的缓存
通过上面的练习可以知道,urlopen可以轻松获取远端html页面信息,然后通过python正则对所需要的数据进行分析,匹配出想要用的数据,然后利用urlretrieve将数据下载到本地。对于访问受限或者对连接数有限制的远程url地址可以采用proxies(代理的方式)连接,如果远程数据量过大,单线程下载太慢的话可以采用多线程下载,这个就是传说中的爬虫。
上面介绍的前两个方法是urllib中最常用的方法,这些方法在获取远程数据的时候,内部会使用URLopener或者 FancyURLOpener类。作为urllib的使用者,我们很少会用到这两个类。如果对urllib的实现感兴趣,或者希望urllib支持更多的协议,可以研究这两个类
urllib2是python自带的模块,有简单请求方法,也有复杂的http验证,http代理方法,今天就介绍几个基本的http请求方法。
urllib2的urlopen方法可以直接添加url即可访问,但是此方法不支持验证和代理的方法,所以后边会介绍urllib2的Request类和opener
urllib2.urlopen
urllib2.urlopen(url,data=None,timeout=1,cafile=None,capath=None,cadefault=False,context=None)
下面是urllib2发起http请求,获取httpcode
In [1]: import urllib2
In [2]: url = ''
In [3]: res = urllib2.urlopen(url)
#读取请求结果
In [5]: print res.read()
this is index.html
#获取httpcode
In [6]: print res.code
200
#获取http请求头
In [7]: print res.headers
Server: nginxsweb
Date: Sat, 07 Jan 2017 02:42:10 GMT
Content-Type: text/html
Content-Length: 19
Last-Modified: Sat, 07 Jan 2017 01:04:12 GMT
Connection: close
ETag: "58703e8c-13"
Accept-Ranges: bytes
urllib2的Request
(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False)
通过http请求发送数据给zabbix登录(非api的登录)
import urllib
import urllib2
url = ''
#这里是zabbix的账户,密码,和点击的操作
data = {'name' : 'admin',
'password' : 'zabbix',
'enter' : 'Sign in' }
#编码上面的数据
data = urllib.urlencode(data)
#实例化Request类
req = urllib2.Request(url, data)
#发送请求
response = urllib2.urlopen(req)
the_page = response.read()
print the_page
urllib2.HTTPBasicAuthHandler
验证nginx的用户进行登录
#初始化一个auth_handler实例它的功能是http验证的类
auth_handler = urllib2.HTTPBasicAuthHandler()
top_level_url = ''
username='admin'
password='nginxs.net'
#调用auth_handler实例里面的密码方法
auth_handler.add_password(realm='Nginxs.net login',uri='
#构建一个opener 对象,它将使用http,https,ftp这三个默认的handlers
opener = urllib2.build_opener(auth_handler)
#安装一个opener作为全局urlopen()使用的对象
urllib2.install_opener(opener)
res=urllib2.urlopen(top_level_url)
print res.read()
urllib2.ProxyHandler
使用代理访问一个网站
url=''
#初始化一个名为proxy代理实例
proxy = urllib2.ProxyHandler({'http':'127.0.0.1:1080'})
#这里创建一个opener对象,这个对象可以处理http,https,ftp等协议,如果你指定了子类参数这个默认的handler将不被使用
opener = urllib2.build_opener(proxy)
#使用open方法打开url
res = opener.open(url)
#查看返回结果
print res.read()
Python爬虫主要使用的是urllib模块,Python2.x版本是urllib2,很多博客里面的示例都是使用urllib2的,因为我使用的是Python3.3.2,所以在文档里面没有urllib2这个模块,import的时候会报错,找不到该模块,应该是已经将他们整合在一起了。
在Python 3以后的版本中,urllib2这个模块已经不单独存在(也就是说当你import urllib2时,系统提示你没这个模块),urllib2被合并到了urllib中,叫做urllib.request 和 urllib.error 。
urllib整个模块分为urllib.request, urllib.parse, urllib.error。
例:
其中
urllib2.urlopen()变成了urllib.request.urlopen()
urllib2.Request()变成了urllib.request.Request()
urllib和urllib2模块之间的区别
在python中,urllib和urllib2不可相互替代的。
整体来说,urllib2是urllib的增强,但是urllib中有urllib2中所没有的函数。
urllib2可以用urllib2.openurl中设置Request参数,来修改Header头。如果你访问一个网站,想更改User Agent(可以伪装你的浏览器),你就要用urllib2.
urllib支持设置编码的函数,urllib.urlencode,在模拟登陆的时候,经常要post编码之后的参数,所以要想不使用第三方库完成模拟登录,你就需要使用urllib。
urllib一般和urllib2一起搭配使用
1.urllib.urlopen(url[,data[,proxies]])
打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作。本例试着打开baidu
import urllib
f = urllib.urlopen('')
firstLine = f.readline() #读取html页面的第一行
print firstLine
urlopen返回对象提供方法:
read() , readline() ,readlines() , fileno() , close() :这些方法的使用方式与文件对象完全一样
info():返回一个httplib.HTTPMessage对象,表示远程服务器返回的头信息
getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
geturl():返回请求的url
2.urllib.urlretrieve(url[,filename[,reporthook[,data]]])
urlretrieve方法将url定位到的html文件下载到你本地的硬盘中。如果不指定filename,则会存为临时文件。
urlretrieve()返回一个二元组(filename,mine_hdrs)
临时存放:
#需要指定存放地址可用 filename = urllib.urlretrieve('',filename='/path/baidu.html')
import urllib
filename = urllib.urlretrieve('')
type(filename)
filename[0]
filename[1]
3.urllib.urlcleanup()
清除由于urllib.urlretrieve()所产生的缓存
4.urllib.quote(url)和urllib.quote_plus(url)
将url数据获取之后,并将其编码,从而适用与URL字符串中,使其能被打印和被web服务器接受。
#屏蔽url中特殊的字符(包括中文),把需要编码的字符转化为 %xx 的形式
urllib.quote('')
urllib.quote_plus('')
5.urllib.unquote(url)和urllib.unquote_plus(url)
与4的函数相反
6.urllib.urlencode(query)
将URL中的键值对以连接符&划分
将dict或者包含两个元素的元组列表转换成url参数。例如 字典{'name': 'dark-bull', 'age': 200}将被转换为"name=dark-bull&age=200"
这里可以与urlopen结合以实现post方法和get方法:
GET 方法:
import urllib
params=urllib.urlencode({'spam':1,'eggs':2,'bacon':0})
#params'eggs=2&bacon=0&spam=1'
f=urllib.urlopen("%s" % params)
print f.read()
import urllib
data = urllib.parse.urlencode(params).encode('utf-8')
req = urllib.request.Request(url, data)
req.add_header('Content-Type', "application/x-www-form-urlencoded")
response = urllib.request.urlopen(req)
the_page = response.read().decode('utf-8')
print(the_page)
如果不做encode,会直接报错:POST data should be bytes or an iterable of bytes. It cannot be of type str.
如果不做decode,看到的都是assic码
urllib模块:
urllib.urlopen(url[,data[,proxies]]) 打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作
urlopen返回对象提供方法:
read() , readline() ,readlines() , fileno() , close() :这些方法的使用方式与文件对象完全一样
info():返回一个httplib.HTTPMessage对象,表示远程服务器返回的头信息
getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
geturl():返回请求的url
urllib.urlencode() 将URL中的键值对以连接符&划分,暂时不支持urldecode();注意:urlencode的参数必须是Dictionary
如:urllib.urlencode({'spam':1,'eggs':2,'bacon':0})
结果为:eggs=2&bacon=0&spam=1
urllib.quote(url)和urllib.quote_plus(url) 将url数据获取之后,并将其编码,从而适用与URL字符串中,使其能被打印和被web服务器接受
如:
print urllib.quote('')
print urllib.quote_plus('')
结果分别为:
http%3A//
http%3A%2F%2F
urllib.unquote(url)和urllib.unquote_plus(url) 与上面正好相反
urllib2模块:
直接请求一个url地址:
urllib2.urlopen(url, data=None) 通过向指定的URL发出请求来获取数据
构造一个request对象信息,然后发送请求:
urllib2.Request(url,data=None,header={},origin_req_host=None) 功能是构造一个请求信息,返回的req就是一个构造好的请求
urllib2.urlopen(url, data=None) 功能是发送刚刚构造好的请求req,并返回一个文件类的对象response,包括了所有的返回信息
response.read() 可以读取到response里面的html
response.info() 可以读到一些额外的响应头信息
主要区别:
urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。这意味着,你不可以通过urllib模块伪装你的User Agent字符串等(伪装浏览器)。
urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。
urllib2模块比较优势的地方是urlliburllib2.urlopen可以接受Request对象作为参数,从而可以控制HTTP Request的header部。
但是urllib.urlretrieve函数以及urllib.quote等一系列quote和unquote功能没有被加入urllib2中,因此有时也需要urllib的辅助
实例:
import urllib
import urllib2
from sys import exit
murl = "http://zhpfbk.blog.51cto.com/"
UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2896.3 Safari/537.36"
### 设置传入的参数,内容为一个dic
value = {'value1':'tkk','value2':'abcd'}
### 对value进行url编码
data = urllib.urlencode(value)
### 设置一个http头,格式为一个dic
header = {'User-Agent':UserAgent}
### 设置一个请求信息对象
req = urllib2.Request(murl,data,header)
print req.get_method()
### 以下内容为发送请求,并处理报错
try:
### 发送请求
resp = urllib2.urlopen(req)
### 获取HTTPError报错,必须设置在URLError之前,包含两个对象,code和reson
except urllib2.HTTPError,e:
print "HTTPError Code: ",e.code
sys.exit(2)
### 获取URLRrror报错,包含一个对象:reson
except urllib2.URLError,reson:
print "Reason: ",reson
sys.exit(2)
else:
### 获取请求的URL地址
print resp.geturl()
### 读取50字节数据
print resp.read(50)
### 获取响应码
print resp.getcode()
### 获取服务器响应头信息
print resp.info()
### 对url进行编码,转化成:http%3A%2F%2F
print urllib.quote_plus('')
print "No problem."
import urllib2
response = urllib2.urlopen('')
html = response.read()
import urllib2
req = urllib2.Request('')
response = urllib2.urlopen(req)
the_page = response.read()
import urllib
import urllib2
url = ''
values = {'name' : 'Michael Foord',
'location' : 'pythontab',
'language' : 'Python' }
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()
>>> import urllib2
>>> import urllib
>>> data = {}
>>> data['name'] = 'Somebody Here'
>>> data['location'] = 'pythontab'
>>> data['language'] = 'Python'
>>> url_values = urllib.urlencode(data)
>>> print url_values
name=blueelwang+Here&language=Python&location=pythontab
>>> url = ''
>>> full_url = url + '?' + url_values
>>> data = urllib2.open(full_url)
import urllib
import urllib2
url = ''
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'name' : 'Michael Foord',
'location' : 'pythontab',
'language' : 'Python' }
headers = { 'User-Agent' : user_agent }
data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()
1、获取url参数。
>>> from urllib import parse
>>> url = r''
>>> parseResult = parse.urlparse(url)
>>> parseResult
ParseResult(scheme='https', netloc='docs.python.org', path='/3.5/search.html', params='', query='q=parse&check_keywords=yes&area=default', fragment='')
>>> param_dict = parse.parse_qs(parseResult.query)
>>> param_dict
{'q': ['parse'], 'check_keywords': ['yes'], 'area': ['default']}
>>> q = param_dict['q'][0]
>>> q
'parse'
#注意:加号会被解码,可能有时并不是我们想要的
>>> parse.parse_qs('proxy=183.222.102.178:8080&task=XXXXX|5-3+2')
{'proxy': ['183.222.102.178:8080'], 'task': ['XXXXX|5-3 2']}
2、parse_qs/parse_qsl
>>> from urllib import parse
>>> parse.parse_qs('action=addblog&job=modify&tid=1766670')
{'tid': ['1766670'], 'action': ['addblog'], 'job': ['modify']} #注意和第三个并不一样
>>> parse.parse_qsl('action=addblog&job=modify&tid=1766670')
[('action', 'addblog'), ('job', 'modify'), ('tid', '1766670')]
>>> dict(parse.parse_qsl('action=addblog&job=modify&tid=1766670')) #注意和第一个并不一样
{'tid': '1766670', 'action': 'addblog', 'job': 'modify'}
3、urlencode
>>> from urllib import parse
>>> query = {
'name': 'walker',
'age': 99,
}
>>> parse.urlencode(query)
'name=walker&age=99'
4、quote/quote_plus
>>> from urllib import parse
>>> parse.quote('a&b/c') #未编码斜线
'a%26b/c'
>>> parse.quote_plus('a&b/c') #编码了斜线
'a%26b%2Fc'
5、unquote/unquote_plus
from urllib import parse
>>> parse.unquote('1+2') #不解码加号
'1+2'
>>> parse.unquote('1+2') #把加号解码为空格
'1 2'
下面是一个简单的代码示例:
#encoding:UTF-8
import urllib.request
def getdata():
url=""
data=urllib.request.urlopen(url).read()
print(data)
getdata()
中文转码,修改一下代码:
#encoding:UTF-8
import urllib.request
def getdata():
url=""
data=urllib.request.urlopen(url).read()
z_data=data.decode('UTF-8')
print(z_data)
getdata()
Python3 urllib GET方式获取数据
GET方式示例【百度搜索】
#encoding:UTF-8
import urllib
import urllib.request
#数据字典
data={}
data['word']='python3'
#注意Python2.x的区别
url_values=urllib.parse.urlencode(data)
print(url_values)
url="/s?"
full_url=url+url_values
data=urllib.request.urlopen(full_url).read()
z_data=data.decode('UTF-8')
print(z_data)
python3 urllib.request 网络请求操作
基本的网络请求示例
import urllib.request
#请求百度网页
resu = urllib.request.urlopen('', data = None, timeout = 10)
print(resu.read(300))
#指定编码请求
with urllib.request.urlopen('') as resu:
print(resu.read(300).decode('GBK'))
#指定编码请求
f = urllib.request.urlopen('')
print(f.read(100).decode('utf-8'))
发送数据请求,CGI程序处理
import urllib.request
req = urllib.request.Request(url='',
... data=b'This data is passed to stdin of the CGI')
f = urllib.request.urlopen(req)
print(f.read().decode('utf-8'))
Got Data: "This data is passed to stdin of the CGI"
PUT请求
import urllib.request
DATA=b'some data'
req = urllib.request.Request(url='', data=DATA,method='PUT')
f = urllib.request.urlopen(req)
print(f.status)
print(f.reason)
基本的HTTP验证,登录请求
import urllib.request
# Create an OpenerDirector with support for Basic HTTP Authentication...
auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm='PDQ Application',
uri='',
user='klem',
passwd='kadidd!ehopper')
opener = urllib.request.build_opener(auth_handler)
# ...and install it globally so it can be used with urlopen.
urllib.request.install_opener(opener)
urllib.request.urlopen('')
支持代理方式验证请求
proxy_handler = urllib.request.ProxyHandler({'http': ''})
proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)
# This time, rather than install the OpenerDirector, we use it directly:
opener.open('')
添加 http headers
import urllib.request
req = urllib.request.Request('')
req.add_header('Referer', '')
r = urllib.request.urlopen(req)
添加 user-agent
import urllib.request
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('')
带参数的GET 请求
import urllib.request
import urllib.parse
params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
f = urllib.request.urlopen("%s" % params)
print(f.read().decode('utf-8'))
带参数的POST请求
import urllib.request
import urllib.parse
data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
data = data.encode('utf-8')
request = urllib.request.Request("")
# adding charset parameter to the Content-Type header.
request.add_header("Content-Type","application/x-www-form-urlencoded;charset=utf-8")
f = urllib.request.urlopen(request, data)
print(f.read().decode('utf-8'))
指定代理方式请求
import urllib.request
proxies = {'http': ''}
opener = urllib.request.FancyURLopener(proxies)
f = opener.open("")
f.read().decode('utf-8')
无添加代理
import urllib.request
opener = urllib.request.FancyURLopener({})
f = opener.open("")
f.read().decode('utf-8')
Python3中urllib详细使用方法(header,代理,超时,认证,异常处理)
urllib是python的一个获取url(Uniform Resource Locators,统一资源定址器)了,我们可以利用它来抓取远程的数据进行保存哦,下面整理了一些关于urllib使用中的一些关于header,代理,超时,认证,异常处理处理方法,下面一起来看看。
python3 抓取网页资源的 N 种方法
1、最简单
import urllib.request
response = urllib.request.urlopen('')
html = response.read()
2、使用 Request
import urllib.request
req = urllib.request.Request('')
response = urllib.request.urlopen(req)
the_page = response.read()
3、发送数据
#! /usr/bin/env python3
import urllib.parse
import urllib.request
url = ''
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {
'act' : 'login',
'login[email]' : 'yzhang@i9i8.com',
'login[password]' : '123456'
}
data = urllib.parse.urlencode(values)
req = urllib.request.Request(url, data)
req.add_header('Referer', '')
response = urllib.request.urlopen(req)
the_page = response.read()
print(the_page.decode("utf8"))
4、发送数据和header
#! /usr/bin/env python3
import urllib.parse
import urllib.request
url = ''
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {
'act' : 'login',
'login[email]' : 'yzhang@i9i8.com',
'login[password]' : '123456'
}
headers = { 'User-Agent' : user_agent }
data = urllib.parse.urlencode(values)
req = urllib.request.Request(url, data, headers)
response = urllib.request.urlopen(req)
the_page = response.read()
print(the_page.decode("utf8"))
5、http 错误
#! /usr/bin/env python3
import urllib.request
req = urllib.request.Request(' ')
try:
urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
print(e.code)
print(e.read().decode("utf8"))
8、HTTP 认证
#! /usr/bin/env python3
import urllib.request
# create a password manager
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
# If we knew the realm, we could use it instead of None.
top_level_url = " /"
password_mgr.add_password(None, top_level_url, 'rekfan', 'xxxxxx')
handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
# create "opener" (OpenerDirector instance)
opener = urllib.request.build_opener(handler)
# use the opener to fetch a URL
a_url = " /"
x = opener.open(a_url)
print(x.read())
# Install the opener.
# Now all calls to urllib.request.urlopen use our opener.
urllib.request.install_opener(opener)
a = urllib.request.urlopen(a_url).read().decode('utf8')
print(a)
9、使用代理
#! /usr/bin/env python3
import urllib.request
proxy_support = urllib.request.ProxyHandler({'sock5': 'localhost:1080'})
opener = urllib.request.build_opener(proxy_support)
urllib.request.install_opener(opener)
a = urllib.request.urlopen(" ").read().decode("utf8")
print(a)
10、超时
#! /usr/bin/env python3
import socket
import urllib.request
# timeout in seconds
timeout = 2
socket.setdefaulttimeout(timeout)
# this call to urllib.request.urlopen now uses the default timeout
# we have set in the socket module
req = urllib.request.Request(' /')
a = urllib.request.urlopen(req).read()
print(a)
① 在Python中通过HTTP下载东西是非常简单的; 实际上,只需要一行代码。urllib.request模块有一个方便的函数urlopen() ,它接受你所要获取的页面地址,然后返回一个类文件对象,您只要调用它的read()方法就可以获得网页的全部内容。没有比这更简单的了。
② urlopen().read()方法总是返回bytes对象,而不是字符串。记住字节仅仅是字节,字符只是一种抽象。 HTTP 服务器不关心抽象的东西。如果你请求一个资源,你得到字节。 如果你需要一个字符串,你需要确定字符编码,并显式的将其转化成字符串。
通过BeautifulSoup 的 find_all方法,找出所有a标签中的href属性中包含http的内容,这就是我们要找的网页的一级链接( 这里不做深度遍历链接)
并返回符合上述条件的a标签的href属性的内容,这就是我们要找的某个网页的所带有的一级链接
1.1 导入模块
#!/usr/bin/env python
from BeautifulSoup import BeautifulSoup #process html
from BeautifulSoup import BeautifulStoneSoup #process xml
import BeautifulSoup #all
1.2 创建对象
doc = ['
hello'
This is paragraph one of ptyhonclub.org.',
'
This is paragraph two of pythonclub.org.',
'']
soup = BeautifulSoup(''.join(doc))
指定编码:
htmlCharset = "GB2312"
soup = BeautifulSoup(respHtml, fromEncoding=htmlCharset)
2.获取tag内容 (以下3种方法等价)
head = soup.find('head')
head = soup.head
head = soup.contents[0].contents[0]
print head
3.获取关系节点
3.1 使用parent获取父节点
body = soup.body
html = body.parent # html是body的父亲
3.2 使用nextSibling, previousSibling获取前后兄弟
head = body.previousSibling # head和body在同一层,是body的前一个兄弟
p1 = body.contents[0] # p1, p2都是body的儿子,我们用contents[0]取得p1
p2 = p1.nextSibling # p2与p1在同一层,是p1的后一个兄弟, 当然body.content[1]也可得到
4.find/findAll用法详解
函数原型:find(name=None, attrs={}, recursive=True, text=None, **kwargs),findAll会返回所有符合要求的结果,并以list返回
第一个是tag的名称,第二个是属性。第3个选择递归,text是判断内容。limit是提取数量限制。**kwargs 就是字典传递了
4.1 tag搜索
find(tagname) # 直接搜索名为tagname的tag 如:find('head')
find(list) # 搜索在list中的tag,如: find(['head', 'body'])
find(dict) # 搜索在dict中的tag,如:find({'head':True, 'body':True})
find(re.compile('')) # 搜索符合正则的tag, 如:find(re.compile('^p')) 搜索以p开头的tag
find(lambda) # 搜索函数返回结果为true的tag, 如:find(lambda name: if len(name) == 1) 搜索长度为1的tag
find(True) # 搜索所有tag,但是不会返回字符串节点
findAll(name, attrs, recursive, text, limit, **kwargs)
示例:
a = urllib2.urlopen('')
b = a.read().decode('utf-8')
soup = BeautifulSoup.BeautifulStoneSoup(b,convertEntities=BeautifulSoup.BeautifulStoneSoup.ALL_ENTITIES).html.head.findAll('link')
for i in soup:
print i['href']
4.2 attrs搜索
find(id='xxx') # 寻找id属性为xxx的
find(attrs={id=re.compile('xxx'), algin='xxx'}) # 寻找id属性符合正则且algin属性为xxx的
find(attrs={id=True, algin=None}) # 寻找有id属性但是没有algin属性的
4.3 text搜索
文字的搜索会导致其他搜索给的值如:tag, attrs都失效。方法与搜索tag一致
print p1.text
# u'This is paragraphone.'
print p2.text
# u'This is paragraphtwo.'
# 注意:1,每个tag的text包括了它以及它子孙的text。2,所有text已经被自动转为unicode,如果需要,可以自行转码encode(xxx)
4.4 recursive和limit属性
recursive=False表示只搜索直接儿子,否则搜索整个子树,默认为True
当使用findAll或者类似返回list的方法时,limit属性用于限制返回的数量,如findAll('p', limit=2): 返回首先找到的两个tag
#!/opt/yrd_soft/bin/python
import re
import urllib2
import requests
import lxml
from bs4 import BeautifulSoup
url = ''
#page=urllib2.urlopen(url)
page=requests.get(url).text
pagesoup=BeautifulSoup(page,'lxml')
for link in pagesoup.find_all(name='a',attrs={"href":re.compile(r'^http:')}):
#print type(link)
print link.get('href')
#encoding=utf-8
#author: walker
#date: 2014-11-26
#summary: 使用BeautifulSoup获取url及其内容
import sys, re, requests, urllib
from bs4 import BeautifulSoup
reload(sys)
sys.setdefaultencoding('utf8')
#给定关键词,获取百度搜索的结果
def GetList(keyword):
keyword = unicode(keyword, 'gb18030')
dic = {'wd': keyword}
urlwd = urllib.urlencode(dic)
print(urlwd)
sn = requests.Session()
url = '/s?ie=utf-8&csq=1&pstg=22&mod=2&isbd=1&cqid=9c0f47b700036f17&istc=8560&ver=0ApvSgUI_ODaje7cp4DVye9X2LZqWiCPEIS&chk=54753dd5&isid=BD651248E4C31919&'
url += urlwd
url += '&ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&rsv_pq=b05765d70003b6c0&rsv_t=ce54Z5LOdER%2Fagxs%2FORKVsCT6cE0zvMTaYpqpgprhExMhsqDACiVefXOze4&_ck=145469.1.129.57.22.735.37'
r = sn.get(url=url)
soup = BeautifulSoup(r.content) #r.text很可能中文乱码
rtn = soup.find('div',id='content_left').find_all(name='a',href=re.compile('baidu.com'))
for item in rtn:
print(item.getText().encode('gb18030'))
print(item['href'])
if __name__ == '__main__':
keyword = '正则表达式'
GetList(keyword)