Urllib发送请求

基本用法

基本的用法就是调用request库,

class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)在编写代码之前把这些属性值填写成自己想要的参数就行了,

高级用法

将介绍“处理器“---Handler。利用它就可以处理Cookies、设置代理等任何HTTP请求中所有的事情。

首先介绍下 urllib.request 模块里的 BaseHandler类,它是所有其他 Handler 的父类,它提供了最基本的 Handler 的方法,例如 default_open()、protocol_request() 方法等。接下来就有各种 Handler 子类继承这个 BaseHandler 类,举例几个如下:

  • HTTPDefaultErrorHandler 用于处理 HTTP 响应错误,错误都会抛出 HTTPError 类型的异常。
  • HTTPRedirectHandler 用于处理重定向。
  • HTTPCookieProcessor 用于处理 Cookies。
  • ProxyHandler 用于设置代理,默认代理为空。
  • HTTPPasswordMgr 用于管理密码,它维护了用户名密码的表。
  • HTTPBasicAuthHandler 用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题。

    更多的Handler可以参考https://docs.python.org/3/library/urllib.request.html#basehandler-objects

    在正常的request中需要使用urlopen,而handler则是需要使用Opener,urlopen()这个方法就是Urllib为我们提供的一个Opener。

认证

有些网站必须要输入用户名和密码,认证成功后才能继续显示。类似的网站比如路由器的管理员登录界面(在浏览器中输入192.168.1.1跳转的界面)。在这里并不是绕过登录界面,而是在模拟请求的时候不会报错。

from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
from urllib.error import URLError username = '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)

代理

设置代理

from urllib.error import URLError
from urllib.request import ProxyHandler, build_opener proxy_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)

Cookie

首先花点时间介绍一下Cookies,登录网站的时候我们常常会发现有些网站自动登录了,而且很长时间都不会失效、有些则是需要我们重新登录(输入用户模型和密码的),这其实涉及到了Session和Cookies的相关知识。HTTP协议是一种无状态的协议,意思是客户端与服务端进行数据交互的时候并不会保存进行的操作,举个例子:当我们加载网页的一张图片,传过来只有半张时停止加载,我们如果不加处理的再去向服务器请求,服务端是不会记住之前传输的操作的,服务端所进行的操作是重新将这张图片完整的数据重新传输一次。所以,HTTP 的无状态是指 HTTP 协议对事务处理是没有记忆能力的,也就是说服务器不知道客户端是什么状态。。这点虽然避免了信息的冗余性(不会要求HTTP协议在进行数据传输时仍然要保存事务处理),但是对于需要用户登录的页面来说,为了保持前后状态,我们肯定不希望将前面的请求全部重传一次,这样过于浪费资源了,所以保持HTTP连接状态的技术就出现了。Session在服务端(网站的服务器),用于保存用户的会话信息,Cookies在客户端。服务器通过识别 Cookies 并鉴定出是哪个用户,然后再判断用户是否是登录状态,然后返回对应的 Response。所以,我们可以这样理解:如果我们将一次登陆成功后的Cookies放在Request Headers里面直接请求服务端,就不必重新模拟登陆了。

当浏览器下一次再请求该网站时,浏览器会把此Cookies 放到 Request Headers 一起提交给服务器,Cookies 携带了 Session ID 信息,服务器检查该 Cookies 即可找到对应的 Session 是什么,然后再判断 Session 来以此来辨认用户状态。所以我们在登录某个网站的时候,登录成功后服务器会告诉客户端设置哪些 Cookies 信息,在后续访问页面时客户端会把 Cookies 发送给服务器,服务器再找到对应的 Session 加以判断,如果 Session 中的某些设置登录状态的变量是有效的,那就证明用户是处于登录状态的,即可返回登录之后才可以查看的网页内容,浏览器进行解析便可以看到了。

好了,下面我们介绍python中与Cookies相关的Handler,首先将网站的Cookies获取下来:

import http.cookiejar, urllib.request

cookie = http.cookiejar.CookieJar()    #申明一个CookieJar对象
handler = urllib.request.HTTPCookieProcessor(cookie) #创建Handler
opener = urllib.request.build_opener(handler) #构建出Opener
response = opener.open('http://www.baidu.com') #执行open()函数
for item in cookie:
print(item.name+"="+item.value)

执行的结果如下:

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

以上就是Cookies的完整样貌,我们可以将这个Cookie保存下来方便我们后面调用:

filename = 'cookies.txt'
#cookie = http.cookiejar.MozillaCookieJar(filename)
cookie = http.cookiejar.LWPCookieJar(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.txt文件如下:

#LWP-Cookies-2.0
Set-Cookie3: BAIDUID="0CE9C56F598E69DB375B7C294AE5C591:FG=1"; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2084-10-14 18:25:19Z"; version=0
Set-Cookie3: BIDUPSID=0CE9C56F598E69DB375B7C294AE5C591; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2084-10-14 18:25:19Z"; version=0
Set-Cookie3: H_PS_PSSID=20048_1448_18240_17944_21089_21192_21161_20929; path="/"; domain=".baidu.com"; path_spec; domain_dot; discard; version=0
Set-Cookie3: PSTM=1474902671; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2084-10-14 18:25:19Z"; version=0
Set-Cookie3: BDSVRTM=0; path="/"; domain="www.baidu.com"; path_spec; discard; version=0
Set-Cookie3: BD_HOME=0; path="/"; domain="www.baidu.com"; path_spec; discard; version=0

接下来利用Cookies的LWPCookieJar格式来读取文件:

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')

Urllib处理异常

在跑程序获取数据中,如果程序中途遇到错误而我们没有写异常处理的时候,尽可能辛辛苦苦跑的数据就损失了;在获取豆瓣电影top250的时候,部分电影的参数不完整,导致爬虫总是会在这中途出现错误。。。更有可能的是,如果网络情况突然变更,要做异常处理,是的网络恢复的时候能继续运行程序。综上,写异常处理真的非常重要!!

HTTPError

  • code,返回 HTTP Status Code,即状态码,比如 404 网页不存在,500 服务器内部错误等等。
  • reason,同父类一样,返回错误的原因。
  • headers,返回 Request Headers。
from urllib import request,error
try:
response = request.urlopen('http://没有这个页面.com/index.htm')
except error.HTTPError as e:
print(e.reason, e.code, e.headers, seq='\n')

Python网络爬虫(一)的更多相关文章

  1. 关于Python网络爬虫实战笔记③

    Python网络爬虫实战笔记③如何下载韩寒博客文章 Python网络爬虫实战笔记③如何下载韩寒博客文章 target:下载全部的文章 1. 博客列表页面规则 也就是, http://blog.sina ...

  2. 关于Python网络爬虫实战笔记①

    python网络爬虫项目实战笔记①如何下载韩寒的博客文章 python网络爬虫项目实战笔记①如何下载韩寒的博客文章 1. 打开韩寒博客列表页面 http://blog.sina.com.cn/s/ar ...

  3. python 网络爬虫(二) BFS不断抓URL并放到文件中

    上一篇的python 网络爬虫(一) 简单demo 还不能叫爬虫,只能说基础吧,因为它没有自动化抓链接的功能. 本篇追加如下功能: [1]广度优先搜索不断抓URL,直到队列为空 [2]把所有的URL写 ...

  4. python网络爬虫学习笔记

    python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...

  5. Python网络爬虫

    http://blog.csdn.net/pi9nc/article/details/9734437 一.网络爬虫的定义 网络爬虫,即Web Spider,是一个很形象的名字. 把互联网比喻成一个蜘蛛 ...

  6. Python 正则表达式 (python网络爬虫)

    昨天 2018 年 01 月 31 日,农历腊月十五日.20:00 左右,152 年一遇的月全食.血月.蓝月将今晚呈现空中,虽然没有看到蓝月亮,血月.月全食也是勉强可以了,还是可以想像一下一瓶蓝月亮洗 ...

  7. Python网络爬虫笔记(五):下载、分析京东P20销售数据

    (一)  分析网页 下载下面这个链接的销售数据 https://item.jd.com/6733026.html#comment 1.      翻页的时候,谷歌F12的Network页签可以看到下面 ...

  8. 如何利用Python网络爬虫抓取微信朋友圈的动态(上)

    今天小编给大家分享一下如何利用Python网络爬虫抓取微信朋友圈的动态信息,实际上如果单独的去爬取朋友圈的话,难度会非常大,因为微信没有提供向网易云音乐这样的API接口,所以很容易找不到门.不过不要慌 ...

  9. 如何利用Python网络爬虫爬取微信朋友圈动态--附代码(下)

    前天给大家分享了如何利用Python网络爬虫爬取微信朋友圈数据的上篇(理论篇),今天给大家分享一下代码实现(实战篇),接着上篇往下继续深入. 一.代码实现 1.修改Scrapy项目中的items.py ...

  10. 【python网络爬虫】之requests相关模块

    python网络爬虫的学习第一步 [python网络爬虫]之0 爬虫与反扒 [python网络爬虫]之一 简单介绍 [python网络爬虫]之二 python uillib库 [python网络爬虫] ...

随机推荐

  1. uimsbf和 bslbf的含义

    bslbf代表位串,即“Bit string, left bit first ”, uimsbf代表无符号整数,即”unsinged integer, most significant bit fir ...

  2. linux命令学习(8):mv命令

    版权声明更新:2017-05-12博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的mv命令. 2. ...

  3. [BZOJ2806][CTSC2012]熟悉的文章(Cheat)

    bzoj luogu 题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么 ...

  4. BZOJ2563阿狸和桃子的游戏

    2563: 阿狸和桃子的游戏 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 952  Solved: 682[Submit][Status][Discu ...

  5. js变量和函数提升的小结

    对于变量和函数一起的提升说法,我比较认同"LittleBear"的说法. 比如: <script> console.log(a)//function a(){} var ...

  6. spark减少提交jar包处理

    spark一个应用,算上依赖一百多兆.每一次都如此,坑. 首先是<packing>jar</packing>这只为打包为jar,在plugin中增加一个assembly插件,这 ...

  7. Guice总结

    Guice总结 Jar包:guice-4.1.0.jar 辅包: guava-15.0.jar aopalliance-.jar javaee-api-6.0-RC2.jar Guice的IoC 两种 ...

  8. java多线程编程核心技术——第三章总结

    第一节等待/通知机制 1.1不使用等待/通知机制实现线程间的通讯 1.2什么是等待/通知机制 1.3等待/通知机制的实现 1.4方法wait()锁释放与notify()锁不释放 1.5当interru ...

  9. 【转】Pro Android学习笔记(十三):用户界面和控制(1):UI开发

    目录(?)[-] UI开发 方式一通过XML文件 方式二通过代码 方式三XML代码 UI开发 先理清一些UI概念: view.widget.control:这三个名词其实没有什么区别,都是一个UI元素 ...

  10. hibernate 数据关联一对一

    第一种一对一 person和card,card的id即作为主键,又作为外键  // 各村对方的一个对象 public class Person { private Integer id; privat ...