文章目录

  • 使用urllib库
    • 1.urllib.request.urlopen()函数
    • urlopen()函数API:
  • 2.urllib.request函数
    • 验证
    • Cookies
    • 保存Cookies
    • 读取Cookies

使用urllib库

首先,了解一下urllib库,它是Python内置的HTTP请求库,也就是说不需要额外安装即可使用。它包含如下4个模块。

request:它是最基本的HTTP请求模块,可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程了。

error:异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止。

parse:一个工具模块,提供了许多URL处理方法,比如拆分、解析、合并等。

robotparser:主要是用来识别网站的robots.txt文件,然后判断哪些网站可以爬,哪些网站不可以爬,它其实用得比较少。

1.urllib.request.urlopen()函数

urllib.request模块提供了最基本的构造HTTP请求的方法,利用它可以模拟浏览器的一个请求发起过程

import urllib.request
response = urllib.request.urlopen("http://www.python.org")
#print(response.read().decode('utf-8'))
# print(type(response)) #class类型
# html = response.read() #读取该网页的html信息,爬取的内容是以 utf-8 编码的bytes对象
# print(html) #打印的时候字符串前面有个 b,表示这是一个bytes对象
#
# #要还原成带中文的html代码,需要对其进行解码,将它变成Unicode编码
# html = html.decode("utf-8")
# print(html)
# print("=======================")

接下来,看看它返回的到底是什么。利用 type() 方法输出响应的类型:

print(type(response))
<class 'http.client.HTTPResponse'>

可以发现,它是一个HTTPResposne类型的对象。它主要包含read()、readinto()、getheader(name)、getheaders()、fileno()等方法,以及msg、version、status、reason、debuglevel、closed等属性。

调用read()方法可以得到返回的网页内容,调用status属性可以得到返回结果的状态码,如200代表请求成功,404代表网页未找到等。

import urllib.requestresponse = urllib.request.urlopen('https://www.python.org')
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))
200
[('Connection', 'close'), ('Content-Length', '49243'), ('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'DENY'), ('Via', '1.1 vegur'), ('Via', '1.1 varnish'), ('Accept-Ranges', 'bytes'), ('Date', 'Wed, 23 Sep 2020 00:49:55 GMT'), ('Via', '1.1 varnish'), ('Age', '1774'), ('X-Served-By', 'cache-bwi5142-BWI, cache-hkg17933-HKG'), ('X-Cache', 'HIT, HIT'), ('X-Cache-Hits', '1, 2695'), ('X-Timer', 'S1600822196.530321,VS0,VE0'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')]
nginx

可见,前两个输出分别输出了响应的状态码和响应的头信息,最后一个输出通过调用getheader()方法并传递一个参数Server获取了响应头中的Server值,结果是nginx,意思是服务器是用Nginx搭建的。

urlopen()函数API:

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

data 参数

如果传递了这个参数,则它的请求方式就不再是GET方式,而是POST方式。

data参数是可选的。如果要添加该参数,并且如果它是字节流编码格式的内容,即bytes类型,则需要通过bytes()方法转化

import urllib.parse
import urllib.requestdata = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
response = urllib.request.urlopen('http://httpbin.org/post', data=data)
print(response.read())

这里我们传递了一个参数word,值是hello。它需要被转码成bytes(字节流)类型。其中转字节流采用了bytes()方法,该方法的第一个参数需要是str(字符串)类型,需要用urllib.parse模块里的urlencode()方法来将参数字典转化为字符串;第二个参数指定编码格式,这里指定为utf8。

这里请求的站点是httpbin.org,它可以提供HTTP请求测试。本次我们请求的URL为http://httpbin.org/post, 这个链接可以用来测试POST请求,它可以输出请求的一些信息,其中包含我们传递的data参数。

{"args": {},"data": "","files": {},"form": {"word": "hello"},"headers": {"Accept-Encoding": "identity","Content-Length": "10","Content-Type": "application/x-www-form-urlencoded","Host": "httpbin.org","User-Agent": "Python-urllib/3.5"},"json": null,"origin": "123.124.23.253","url": "http://httpbin.org/post"
}

我们传递的参数出现在了form字段中,这表明是模拟了表单提交的方式,以POST方式传输数据。

timeout 参数

timeout参数用于设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,就会使用全局默认时间。它支持HTTP、HTTPS、FTP请求。

这里我们设置超时时间是1秒。程序1秒过后,服务器依然没有响应,于是抛出了URLError异常。该异常属于urllib.error模块,错误原因是超时。

因此,可以通过设置这个超时时间来控制一个网页如果长时间未响应,就跳过它的抓取。这可以利用try except语句来实现,相关代码如下:

import urllib.requestresponse = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
print(response.read())
import socket
import urllib.request
import urllib.errortry:response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
except urllib.error.URLError as e:if isinstance(e.reason, socket.timeout):print('TIME OUT')
TIME OUT

2.urllib.request函数

构造方法如下:

class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

第一个参数url用于请求URL,这是必传参数,其他都是可选参数。

第二个参数data如果要传,必须传bytes(字节流)类型的。如果它是字典,可以先用urllib.parse模块里的urlencode()编码。

第三个参数headers是一个字典,它就是请求头,我们可以在构造请求时通过headers参数直接构造,也可以通过调用请求实例的add_header()方法添加。
添加请求头最常用的用法就是通过修改User-Agent来伪装浏览器,默认的User-Agent是Python-urllib,我们可以通过修改它来伪装浏览器。比如要伪装火狐浏览器,你可以把它设置为:

Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11

第四个参数origin_req_host指的是请求方的host名称或者IP地址。

第五个参数unverifiable表示这个请求是否是无法验证的,默认是False,意思就是说用户没有足够权限来选择接收这个请求的结果。例如,我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,这时unverifiable的值就是True。

第六个参数method是一个字符串,用来指示请求使用的方法,比如GET、POST和PUT等。
下面我们传入多个参数构建请求来看一下:

from urllib import request, parseurl = 'http://httpbin.org/post'
headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)','Host': 'httpbin.org'
}
dict = {'name': 'Germey'
}
data = bytes(parse.urlencode(dict), encoding='utf8')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))

这里我们通过4个参数构造了一个请求,其中url即请求URL,headers中指定了User-Agent和Host,参数data用urlencode()和bytes()方法转成字节流。另外,指定了请求方式为POST。

运行结果如下:

{"args": {}, "data": "", "files": {}, "form": {"name": "Germey"}, "headers": {"Accept-Encoding": "identity", "Content-Length": "11", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)"}, "json": null, "origin": "219.224.169.11", "url": "http://httpbin.org/post"
}

另外,headers也可以用add_header()方法来添加:

req = request.Request(url=url, data=data, method='POST')
req.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')

验证

有些网站在打开时就会弹出提示框,直接提示你输入用户名和密码,验证成功后才能查看页面,如图3-2所示。

借助HTTPBasicAuthHandler可以完成上面的请求,相关代码如下:

from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
from urllib.error import URLErrorusername = 'username'
password = 'password'
url = 'http://localhost:5000/'p = HTTPPasswordMgrWithDefaultRealm()
p.add_password(None, url, username, password)
auth_handler = HTTPBasicAuthHandler(p)
opener = build_opener(auth_handler)try:result = opener.open(url)html = result.read().decode('utf-8')print(html)
except URLError as e:print(e.reason)

这里首先实例化HTTPBasicAuthHandler对象,其参数是HTTPPasswordMgrWithDefaultRealm对象,它利用add_password()添加进去用户名和密码,这样就建立了一个处理验证的Handler。

接下来,利用这个Handler并使用build_opener()方法构建一个Opener,这个Opener在发送请求时就相当于已经验证成功了。

接下来,利用Opener的open()方法打开链接,就可以完成验证了。这里获取到的结果就是验证后的页面源码内容。

代理

在做爬虫的时候,免不了要使用代理,如果要添加代理,可以这样做:

from urllib.error import URLError
from urllib.request import ProxyHandler, build_openerproxy_handler = ProxyHandler({'http': 'http://127.0.0.1:9743','https': 'https://127.0.0.1:9743'
})
opener = build_opener(proxy_handler)
try:response = opener.open('https://www.baidu.com')print(response.read().decode('utf-8'))
except URLError as e:print(e.reason)

这里我们在本地搭建了一个代理,它运行在9743端口上。

这里使用了ProxyHandler,其参数是一个字典,键名是协议类型(比如HTTP或者HTTPS等),键值是代理链接,可以添加多个代理。

然后,利用这个Handler及build_opener()方法构造一个Opener,之后发送请求即可。

Cookies

import http.cookiejar, urllib.requestcookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
for item in cookie:print(item.name+"="+item.value)

首先,我们必须声明一个CookieJar对象。接下来,就需要利用HTTPCookieProcessor来构建一个Handler,最后利用build_opener()方法构建出Opener,执行open()函数即可。

运行结果如下:

BAIDUID=2E65A683F8A8BA3DF521469DF8EFF1E1:FG=1
BIDUPSID=2E65A683F8A8BA3DF521469DF8EFF1E1
H_PS_PSSID=20987_1421_18282_17949_21122_17001_21227_21189_21161_20927
PSTM=1474900615
BDSVRTM=0
BD_HOME=0

可以看到,这里输出了每条Cookie的名称和值。

保存Cookies

filename = 'cookies.txt'
cookie = http.cookiejar.MozillaCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard=True, ignore_expires=True)

这时CookieJar就需要换成MozillaCookieJar,它在生成文件时会用到,是CookieJar的子类,可以用来处理Cookies和文件相关的事件,比如读取和保存Cookies,可以将Cookies保存成Mozilla型浏览器的Cookies格式。

读取Cookies

cookie = http.cookiejar.LWPCookieJar()
cookie.load('cookies.txt', ignore_discard=True, ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))

可以看到,这里调用load()方法来读取本地的Cookies文件,获取到了Cookies的内容。不过前提是我们首先生成了LWPCookieJar格式的Cookies,并保存成文件,然后读取Cookies之后使用同样的方法构建Handler和Opener即可完成操作。

python网络爬虫学习笔记(三):urllib库的使用相关推荐

  1. python网络爬虫学习笔记(6)动态网页抓取(一)知识

    文章目录 网络爬虫学习笔记(2) 1 资料 2 笔记 2-1 动态抓取概述 2-2 通过浏览器审查元素解析真实网页地址 2-3 网页URL地址的规律 2-4 json库 2-5 通过Selenium模 ...

  2. python网络爬虫学习笔记(7)动态网页抓取(二)实践

    文章目录 1 资料 2 笔记 2-1 准备 2-1-1. 网址 2-2-2 文本位置 2-2 代码 2-2-1 原型 2-2-2 ver0.1 1 资料 <Python网络爬虫从入门到实践> ...

  3. Python网络爬虫学习笔记(二)基本库的使用

    基本库的使用 最基础的 HTTP 库有 urllib . httplib2 . requests . treq 等 . 使用urlib urlib 包含四个模块 口 request : 它是最基本的 ...

  4. python 网络爬虫学习笔记(一)

    为了方便,在Windows下我用了PyCharm,个人感觉这是一款优秀的python学习软件.爬虫,即网络爬虫,大家可以理解为在网络上爬行的一直蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去 ...

  5. python网络爬虫学习笔记2

    1.fiddler的使用 (1)右上是HTTP请求信息, 右下是http响应信息,点击黄色条解码 (2)Raw请求详细信息,raw响应所有信息 (3)webForms请求所带参数 (4)json接口响 ...

  6. python网络爬虫学习笔记(四):异常处理

    urllib的error模块定义了由request模块产生的异常.如果出现了问题,request模块便会抛出error模块中定义的异常. 1.URLError URLError类来自urllib库的e ...

  7. python网络爬虫学习笔记(五):urllib.parse库

    urllib.parse库定义了处理URL的标准接口,例如实现URL各部分的抽取.合并以及链接转换.它支持如下协议的URL处理:file.ftp.gopher.hdl.http.https等. 1.u ...

  8. python网络爬虫学习笔记(六):Requests库的使用

    文章目录 1.基础操作 1.1 GET请求 1.2 post请求 1.3 响应 2.高级用法 1.1 文件上传 2.2 Cookies 2.3 会话维持 2.4 SSL证书验证 2.5 代理设置 2. ...

  9. Python网络爬虫学习笔记(十):PyQuery库的使用

    文章目录 1.初始化 1.1 字符串初始化 1.2 URL初始化 1.3 文件初始化 2.CSS选择器 3.查找节点 3.1 子节点 3.2 父节点 3.3 兄弟节点 遍历 4.获取信息 4.1 获取 ...

最新文章

  1. 怎么把加载图标去掉_怎样在PCB上绘制图标
  2. 多线程Java服务器简单实现
  3. Time to First Byte(TTFB)与Web性能优化
  4. linux netty udp服务端,Netty实现简单UDP服务器(示例代码)
  5. WPF游戏,使用move游戏开发
  6. ES6新特性之map和reduce方法的使用
  7. AngularJs 相应回车事件
  8. 微型计算机强化训练的答案,微型计算机第8章+强化训练
  9. 大漠插件最新版7.2107
  10. java你应该学会什么
  11. SiC MOSFET动态测试上位机软件使用说明
  12. PCI Express 2D 多媒体显卡_IOEHM-GC_V1.0 Mini-PCIe 显卡_嵌入式行业图像显示_视频加速和2D加速功能
  13. 傅佩荣谈道家逍遥自在的人生
  14. 10G XFP万兆光模块全类型介绍
  15. 旭日图(Sunburst)
  16. MySQL关键字,主关键字,候选关键字
  17. Rockset:最具潜力、最值得加入的大数据初创公司
  18. java基础之集合篇
  19. 服务器选择SATA还是SCSI
  20. 【Energy Big Data】能源互联网和电力大数据

热门文章

  1. Url解码,兼容utf-8和gb2312
  2. Domain Model:业务对象的进一步设计
  3. 北京联通光猫 F427 路由改桥接的方法
  4. 静态Web开发 JavaScript
  5. .Net给图片添加水印效果
  6. IE9预览版已全面支持HTML5标准
  7. Oracle多行记录合并/连接/聚合字符串的几种方法
  8. 设计模式再学习之简单工厂模式
  9. 那年学过的Quartz框架笔记
  10. shell中的正则表达式