Python爬虫常用库之urllib详解

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介:

以下为个人在学习过程中做的笔记总结之爬虫常用库urllib


urlib库为python3的HTTP内置请求库


urilib的四个模块:

  • urllib.request:用于获取网页的响应内容

  • urllib.error:异常处理模块,用于处理异常的模块

  • urllib.parse:用于解析url

  • urllib.robotparse:用于解析robots.txt,主要用于看哪些网站不能进行爬取,不过少用


1 urllib.request


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

  • url:为请求网址

  • data:请求时需要发送的参数

  • timeout:超时设置,在该时间范围内返回请求内容就不会报错


示例代码:


 1from urllib import request
2
3# 请求获取网页返回内容
4response = request.urlopen('https://movie.douban.com/')
5# 获取网页返回内容
6print(response.read().decode('utf-8'))
7# 获取状态码
8print(response.status)
9# 获取请求头
10print(response.getheaders())


1# 对请求头进行遍历
2for k, v in response.getheaders():
3 print(k, '=', v)


可以使用上面的代码对一些网站进行请求了,但是当需要一些反爬网站时,这就不行了,这时我们需要适当地增加请求头进行请求,这时就需要使用复杂一点的代码了,这时我们需要用到Request对象


代码示例:


1# 请求头
2headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'}
3requests = request.Request('https://movie.douban.com/', headers=headers) # 加入自己的请求头更加接近浏览器
4# 进行请求,把Request对象传入urlopen参数中
5response = request.urlopen(requests)
6print(response.read().decode('utf-8'))


这个我添加了请求头进行请求,使我发送的请求更加接近浏览器的行为。可以对应一些反爬网站了


如果网站需要进行登陆,这时需要用到post方法,用上面的也是可以的。代码如下:


 1from urllib import request, parse
2# 使用post方法来进行模拟登陆豆瓣
3data = {'source': 'None',
4 'redir': 'https://www.douban.com/',
5 'form_email': 'user',
6 'form_password': 'passwd',
7 'remember': 'on',
8 'login': '登录'}
9# 将data的字典类型转换为get请求方式
10data = bytes(parse.urlencode(data), encoding='utf-8')
11requests = request.Request('https://accounts.douban.com/login', headers=headers, data=data, method='POST')
12response = request.urlopen(requests)
13print(response.read().decode('utf-8'))


这里我用到了data的参数把登陆需要的参数传进去,还加了个请求方法Method


parse.urlencode()后面有讲


这里还有另外一种添加请求头的方法


Request.add_header(): 参数有两个,分别为请求头对应的键和值,这种方法一次只能添加一个请求头,添加多个需要用到循环或者直接用前面的方法添加多个请求头


在登陆了网站之后,我们需要用到cookie来保存登陆信息,这时就需要获取cookie了。urllib获取cookie比较麻烦。


代码示例如下:


 1from http import cookiejar
2# 获取cookie
3cookie = cookiejar.CookieJar()
4# 获取助手把cookie传进去
5handler = request.HTTPCookieProcessor(cookie)
6# 获取opener进行请求网站
7opener = request.build_opener(handler)
8# 请求网页
9response = opener.open('https://movie.douban.com/')
10# 打印cookie
11for c in cookie:
12 print(c.name, '=', c.value)


单纯地打印没什么用,我们需要把他存入文件来保存,下次使用时再次加载cookie来登陆


保存cookie为文件:


1from http import cookiejar
2# 将cookie保存在文件中
3filename = 'cookie.txt'
4cookie = cookiejar.MozillaCookieJar(filename) # 表示使用Mozilla的cookie方式存储和读取
5handler = request.HTTPCookieProcessor(cookie)
6opener = request.build_opener(handler)
7opener.open('https://movie.douban.com/')
8# 保存文件
9cookie.save(ignore_discard=True, ignore_expires=True)


另一种保存方法:


1from http import cookiejar
2cookie = cookiejar.LWPCookieJar(filename) # 表示 Set-Cookie3 文件格式存储和读取
3handler = request.HTTPCookieProcessor(cookie)
4opener = request.build_opener(handler)
5opener.open('https://movie.douban.com/')
6# 保存文件
7cookie.save(ignore_discard=True, ignore_expires=True)


这两种保存格式都是不一样的,需要保存的内容一样。


保存可以了,这时就需要用到加载了,当然也可以。代码如下:


1from http import cookiejar
2# 从cookie文件加载到网页上实现记住登陆
3cookie = cookiejar.LWPCookieJar()
4# 加载文件
5cookie.load(filename, ignore_discard=True, ignore_expires=True)
6handler = request.HTTPCookieProcessor(cookie)
7opener = request.build_opener(handler)
8opener.open('https://movie.douban.com/')

这样就可以实现不用密码进行登陆了。


cookie小总结:在操作cookie时,都是分五步,如下:


  1. 进行导包,至关重要的一步,不导包直接出错。

  2. 获取cookie处理对象,使用cookiejar包

  3. 创建cookie处理器,使用request.HTTPCookieJarProcessor()

  4. 利用cookie处理器构建opener,使用request.build_opener()

  5. 进行请求网站,用opener.open(),这个不能用request.urlopen()


如果有时你在同一ip连续多次发送请求,会有被封ip的可能,这时我们还需要用到代理ip进行爬取,代码如下:


1proxy = request.ProxyHandler({
2 'https': 'https://106.60.34.111:80'
3})
4opener = request.build_opener(proxy)
5opener.open('https://movie.douban.com/', timeout=1)


可以看到越复杂的请求都需要用到request.build_opener(),这个方法有点重要,请记住哈


2 urllib.error


将上面的使用代理ip的请求进行异常处理,如下:


 1from urllib import request, error
2try:
3 proxy = request.ProxyHandler({
4 'https': 'https://106.60.34.111:80'
5 })
6 opener = request.build_opener(proxy)
7 opener.open('https://movie.douban.com/', timeout=1)
8except error.HTTPError as e:
9 print(e.reason(), e.code(), e.headers())
10except error.URLError as e:
11 print(e.reason)


因为有时这个ip或许也被封了,有可能会抛出异常,所以我们为了让程序运行下去进而进行捕捉程序


  • error.URLError: 这个是url的一些问题,这个异常只有一个reason属性

  • error.HTTPError:这个是error.URLError的子类,所以在与上面的混合使用时需要将这个异常放到前面,这个异常是一些请求错误,有三个方法,.reason(), .code(), .headers(),所以在捕捉异常时通常先使用这个


3 urllib.parse


解析url:urllib.parse.urlparse(url, scheme='', allow_fragments=True)


简单的使用:


1from urllib import request, parse
2# 解析url
3print(parse.urlparse('https://movie.douban.com/'))
4print(parse.urlparse('https://movie.douban.com/', scheme='http'))
5print(parse.urlparse('movie.douban.com/', scheme='http'))
6# 下面是结果
7ParseResult(scheme='https', netloc='movie.douban.com', path='/', params='', query='', fragment='')
8ParseResult(scheme='https', netloc='movie.douban.com', path='/', params='', query='', fragment='')
9ParseResult(scheme='http', netloc='', path='movie.douban.com/', params='', query='', fragment='')


可以看出加了scheme参数和没加的返回结果是有区别的。而当scheme协议加了,而前面的url也包含协议,一般会忽略后面的scheme参数


既然后解析url,那当然也有反解析url,就是把元素串连成一个url


1from urllib import parse
2# 将列表元素拼接成url
3url = ['http', 'www', 'baidu', 'com', 'dfdf', 'eddffa'] # 这里至少需要6个元素(我乱写的,请忽视)
4print(parse.urlunparse(url))
5# 下面是结果
6http://www/baidu;com?dfdf#eddffa


urlparse()接收一个列表的参数,而且列表的长度是有要求的,是必须六个参数以上,要不会抛出异常


1Traceback (most recent call last):
2 File "E:/anaconda/python_project/python3_spider/urllib_test.py", line 107, in <module>
3 print(parse.urlunparse(url))
4 File "E:\anaconda\lib\urllib\parse.py", line 454, in urlunparse
5 _coerce_args(*components))
6ValueError: not enough values to unpack (expected 7, got 6)


urllib.parse.urljoin():这个是将第二个参数的url缺少的部分用第一个参数的url补齐


1# 连接两个参数的url, 将第二个参数中缺的部分用第一个参数的补齐
2print(parse.urljoin('https://movie.douban.com/', 'index'))
3print(parse.urljoin('https://movie.douban.com/', 'https://accounts.douban.com/login'))
4# 下面是结果
5https://movie.douban.com/index
6https://accounts.douban.com/login


urllib.parse.urlencode():这个方法是将字典类型的参数转为请求为get方式的字符串


1data = {'name': 'sergiojuue', 'sex': 'boy'}
2data = parse.urlencode(data)
3print('https://accounts.douban.com/login'+data)
4# 下面是结果
5https://accounts.douban.com/loginname=sergiojuue&sex=boy


4 结语

还有个urllib.robotparse库少用,就不说了,留给以后需要再去查文档吧。


上面的只是我在学习过程中的总结,如果有什么错误的话,欢迎在留言区指出,还有就是需要查看更多用法的请查看文档https://docs.python.org/3/library/urllib.html


需要代码的可以去我的github上面fork,给个star也行!


github:https://github.com/SergioJune/gongzhonghao_code/blob/master/python3_spider/urllib_test.py


学习过程中看的大多是崔庆才大佬的视频:https://edu.hellobi.com/course/157


from:https://mp.weixin.qq.com/s?__biz=MzI5NDY1MjQzNA==&mid=2247485940&idx=1&sn=3fabf8c9bb52395675cd71db65cc9109&chksm=ec5ed689db295f9f01f9eb56b95a25fe8221e516969a7ec30794e41fd51fbe582add5002decd&mpshare=1&scene=23&srcid=0329fazECXVxm2F0SylQ9Waw%23rd

目录
相关文章
|
16天前
|
数据采集 存储 XML
Python爬虫定义入门知识
Python爬虫是用于自动化抓取互联网数据的程序。其基本概念包括爬虫、请求、响应和解析。常用库有Requests、BeautifulSoup、Scrapy和Selenium。工作流程包括发送请求、接收响应、解析数据和存储数据。注意事项包括遵守Robots协议、避免过度请求、处理异常和确保数据合法性。Python爬虫强大而灵活,但使用时需遵守法律法规。
|
17天前
|
数据采集 缓存 定位技术
网络延迟对Python爬虫速度的影响分析
网络延迟对Python爬虫速度的影响分析
|
18天前
|
数据采集 Web App开发 监控
高效爬取B站评论:Python爬虫的最佳实践
高效爬取B站评论:Python爬虫的最佳实践
|
22天前
|
调度 开发者 Python
Python中的异步编程:理解asyncio库
在Python的世界里,异步编程是一种高效处理I/O密集型任务的方法。本文将深入探讨Python的asyncio库,它是实现异步编程的核心。我们将从asyncio的基本概念出发,逐步解析事件循环、协程、任务和期货的概念,并通过实例展示如何使用asyncio来编写异步代码。不同于传统的同步编程,异步编程能够让程序在等待I/O操作完成时释放资源去处理其他任务,从而提高程序的整体效率和响应速度。
|
11天前
|
XML 存储 数据库
Python中的xmltodict库
xmltodict是Python中用于处理XML数据的强大库,可将XML数据与Python字典相互转换,适用于Web服务、配置文件读取及数据转换等场景。通过`parse`和`unparse`函数,轻松实现XML与字典间的转换,支持复杂结构和属性处理,并能有效管理错误。此外,还提供了实战案例,展示如何从XML配置文件中读取数据库连接信息并使用。
Python中的xmltodict库
|
19天前
|
数据库 Python
异步编程不再难!Python asyncio库实战,让你的代码流畅如丝!
在编程中,随着应用复杂度的提升,对并发和异步处理的需求日益增长。Python的asyncio库通过async和await关键字,简化了异步编程,使其变得流畅高效。本文将通过实战示例,介绍异步编程的基本概念、如何使用asyncio编写异步代码以及处理多个异步任务的方法,帮助你掌握异步编程技巧,提高代码性能。
53 4
|
19天前
|
API 数据处理 Python
探秘Python并发新世界:asyncio库,让你的代码并发更优雅!
在Python编程中,随着网络应用和数据处理需求的增长,并发编程变得愈发重要。asyncio库作为Python 3.4及以上版本的标准库,以其简洁的API和强大的异步编程能力,成为提升性能和优化资源利用的关键工具。本文介绍了asyncio的基本概念、异步函数的定义与使用、并发控制和资源管理等核心功能,通过具体示例展示了如何高效地编写并发代码。
27 2
|
19天前
|
数据采集 存储 JSON
Python爬虫开发中的分析与方案制定
Python爬虫开发中的分析与方案制定
|
10天前
|
数据采集 JavaScript 程序员
探索CSDN博客数据:使用Python爬虫技术
本文介绍了如何利用Python的requests和pyquery库爬取CSDN博客数据,包括环境准备、代码解析及注意事项,适合初学者学习。
42 0
|
17天前
|
数据采集 数据可视化 数据挖掘
利用Python进行数据分析:Pandas库实战指南
利用Python进行数据分析:Pandas库实战指南