前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python中的urllib模块中的方法

python中的urllib模块中的方法

作者头像
py3study
修改2023-09-20 19:53:31
1.9K0
修改2023-09-20 19:53:31
举报
文章被收录于专栏:python3python3python3

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状态码。(详情参考https://tools.ietf.org/html/rfc7231#section-6)

                          如果是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 = 'http://www.baidu.com'

#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='http://www.baidu.com'

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('http://www.51cto.com')

>>>res.read()

。。。。。。(一堆源代码)

>>>res.readline()

'<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 

Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n'

>>>res.readlines()

。。。(list形式的一堆源码)

>>>res.info()

<httplib.HTTPMessage instance at0x1a02638>

>>>res.getcode()

200

>>>res.geturl()

'http://www.51cto.com' 

#最后关闭连接

>>> 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='http://www.51cto.com'

>>> 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='http://www.51cto.com'

# 将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('http://www.51cto.comm')

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('http://www.51cto.com') 

>>>res.read()

。。。。。。(一堆网页代码)

>>>res.readline()

'<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n' 

。。。。

>>>res.readlines()

。。。(list形式的一堆网页代码)

>>>res.info()

<httplib.HTTPMessage instance at0x1a02638>

>>> response.getcode()  # 返回Http状态码

    200

>>> response.geturl() # 返回请求的url地址 

    'http://www.51cto.com'

>>> 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 = 'http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tar.bz2'

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 = 'http://test.nginxs.net/index.html'

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 = 'http://192.168.198.116/index.php'

#这里是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 = 'http://test.nginxs.net/limit/views.html'

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='http://new.nginxs.net/ip.php'

#初始化一个名为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('http://www.baidu.com')

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('http://www.baidu.com',filename='/path/baidu.html')

import urllib

filename = urllib.urlretrieve('http://www.baidu.com')

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('http://www.baidu.com')

urllib.quote_plus('http://www.baidu.com')

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("http://python.org/query?%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('http://www.baidu.com')

        print urllib.quote_plus('http://www.baidu.com')

     结果分别为:                      

        http%3A//www.baidu.com

        http%3A%2F%2Fwww.baidu.com

 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%2Fwww.baidu.com

    print urllib.quote_plus('http://www.baidu.com')

    print "No problem."

import urllib2 

response = urllib2.urlopen('http://python.org/') 

html = response.read()

import urllib2 

req = urllib2.Request('http://www.pythontab.com') 

response = urllib2.urlopen(req) 

the_page = response.read()

import urllib 

import urllib2 

url = 'http://www.pythontab.com' 

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 = 'http://www.pythontab.com' 

>>> full_url = url + '?' + url_values 

>>> data = urllib2.open(full_url)

import urllib 

import urllib2 

url = 'http://www.pythontab.com' 

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'https://docs.python.org/3.5/search.html?q=parse&check_keywords=yes&area=default'

>>> 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="http://www.baidu.com"  

    data=urllib.request.urlopen(url).read()  

    print(data)  

getdata()  

中文转码,修改一下代码:

#encoding:UTF-8  

import urllib.request  

def getdata():  

    url="http://www.baidu.com"  

    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="http://www.baidu.com/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('http://www.baidu.com', data = None, timeout = 10)

print(resu.read(300))

#指定编码请求

with urllib.request.urlopen('http://www.baidu.com') as resu:

    print(resu.read(300).decode('GBK'))

#指定编码请求

f = urllib.request.urlopen('http://www.baidu.com')

print(f.read(100).decode('utf-8'))

发送数据请求,CGI程序处理

import urllib.request

req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',

...                       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='http://localhost:8080', 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='https://mahler:8092/site-updates.py',

                          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('http://www.example.com/login.html')

支持代理方式验证请求

proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})

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://www.example.com/login.html')

添加 http headers

import urllib.request

req = urllib.request.Request('http://www.example.com/')

req.add_header('Referer', 'http://www.python.org/')

r = urllib.request.urlopen(req)

添加 user-agent

import urllib.request

opener = urllib.request.build_opener()

opener.addheaders = [('User-agent', 'Mozilla/5.0')]

opener.open('http://www.example.com/')

带参数的GET 请求

import urllib.request

import urllib.parse

params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})

f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query?%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("http://requestb.in/xrbl82xr")

# 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': 'http://proxy.example.com:8080/'}

opener = urllib.request.FancyURLopener(proxies)

f = opener.open("http://www.python.org")

f.read().decode('utf-8')

无添加代理

import urllib.request

opener = urllib.request.FancyURLopener({})

f = opener.open("http://www.python.org/")

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('http://python.org/')

html = response.read()

2、使用 Request

import urllib.request

req = urllib.request.Request('http://python.org/')

response = urllib.request.urlopen(req)

the_page = response.read()

3、发送数据

#! /usr/bin/env python3

import urllib.parse

import urllib.request

url = 'http://localhost/login.php'

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', 'http://www.python.org/')

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 = 'http://localhost/login.php'

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('http://www.111cn.net ')

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 = "https://www.111cn.net /"

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 = "https://www.111cn.net /"

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("http://www.111cn.net ").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('http://www.111cn.net /')

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 = ['<html><head>hello<title>PythonClub.org</title></head>',

       '<body><p id="firstpara" align="center">This is paragraph <b>one</b> of ptyhonclub.org.',

       '<p id="secondpara" align="blah">This is paragraph <b>two</b> of pythonclub.org.',

       '</html>']

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('http://www.baidu.com')

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 = 'http://www.baidu.com'

#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 = 'http://www.baidu.com/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)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档