python网络爬虫(二)基本库的使用urllib/requests

使用urllib

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

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

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

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

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

发送请求

  • urlopen:

response = urllib.request.urlopen(‘https://www.python.org’)

可选参数:
data 参数如果要添加该参数,需要使用 bytes 方法将参数转化为字节流编码格式的内容,即 bytes 类型。另外,如果传递了这个参数,则它的请求方式就不再是 GET 方式,而是 POST 方式。

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

  • Request:

request = urllib.request.Request(‘https://python.org’)

response = urllib.request.urlopen(request)

参数:

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

data 如果要传,必须传 bytes(字节流)类型的。

headers 是一个字典,它就是请求头

unverifiable 表示这个请求是否是无法验证的,默认是 False,意思就是说用户没有足够权限来选择接收这个请求的结果

method 是一个字符串,用来指示请求使用的方法

各种 Handler 子类继承这个 BaseHandler 类,举例如下。

  • HTTPDefaultErrorHandler 用于处理 HTTP 响应错误,错误都会抛出 HTTPError 类型的异常。

  • HTTPRedirectHandler 用于处理重定向。

  • HTTPCookieProcessor 用于处理 Cookies。

  • ProxyHandler 用于设置代理,默认代理为空。

  • HTTPPasswordMgr 用于管理密码,它维护了用户名密码的表。

  • HTTPBasicAuthHandler 用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题。

处理异常

  • URLError:

URLError 类来自 urllib 库的 error 模块,它继承自 OSError 类,是 error 异常模块的基类,由 request 模块产生的异常都可以通过捕获这个类来处理。

它具有一个属性 reason,即返回错误的原因。

  • HTTPError:

它是 URLError 的子类,专门用来处理 HTTP 请求错误,比如认证请求失败等。它有如下 3 个属性。

  • code:返回 HTTP 状态码,比如 404 表示网页不存在,500 表示服务器内部错误等。

  • reason:同父类一样,用于返回错误的原因。

  • headers:返回请求头。

解析链接

  • urlparse:实现 URL 的识别和分段

  • urlunparse:将分段合并为url

  • urlsplit:这个方法和 urlparse 方法非常相似,只不过它不再单独解析 params 这一部分,只返回 5 个结果

  • urlunsplit:与 urlunparse 方法类似,它也是将链接各个部分组合成完整链接的方法,传入的参数也是一个可迭代对象,例如列表、元组等,唯一的区别是长度必须为 5

  • urljoin:我们可以提供一个 base_url(基础链接)作为第一个参数,将新的链接作为第二个参数

  • urlencode:为了更加方便地构造参数,我们会事先用字典来表示。要转化为 URL 的参数时,只需要调用该方法即可。

  • parse_qs:有一串 GET 请求参数,利用 parse_qs 方法,就可以将它转回字典

  • parse_qsl:用于将参数转化为元组组成的列表

  • unquote:进行 URL 解码

  • quote:该方法可以将内容转化为 URL 编码的格式。URL 中带有中文参数时,有时可能会导致乱码的问题,此时用这个方法可以将中文字符转化为 URL 编码

使用requests

抓取网页

import requests
import reheaders = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
r = requests.get("https://www.zhihu.com/explore", headers=headers)
pattern = re.compile('explore-feed.*?question_link.*?>(.*?)</a>', re.S)
titles = re.findall(pattern, r.text)
print(titles)

目前可以使用的’User-Agent’: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36’

对于网页的内容这里使用正则表达式进行匹配

抓取二进制数据

图片、音频、视频这些文件本质上都是由二进制码组成的,由于有特定的保存格式和对应的解析方式,我们才可以看到这些形形色色的多媒体。所以,想要抓取它们,就要拿到它们的二进制码。

以 GitHub 的站点图标为例来看一下:

import requestsr = requests.get("https://github.com/favicon.ico")
print(r.text)
print(r.content)

运行结果

在这里插入图片描述

可以注意到,前者出现了乱码,后者结果前带有一个 b,这代表是 bytes 类型的数据。由于图片是二进制数据,所以前者在打印时转化为 str 类型,也就是图片直接转化为字符串,这理所当然会出现乱码。

接着,我们将刚才提取到的图片保存下来:

r = requests.get("https://github.com/favicon.ico")
with open('favicon.ico', 'wb') as f:f.write(r.content)

同样地,音频和视频文件也可以用这种方法获取。

添加headers

与 urllib.request 一样,我们也可以通过 headers 参数来传递头信息。

POST请求

data = {'name': 'germey', 'age': '22'}
r = requests.post("http://httpbin.org/post", data=data)

响应

发送请求后,得到的自然就是响应。在上面的实例中,我们使用 text 和 content 获取了响应的内容。此外,还有很多属性和方法可以用来获取其他信息,比如状态码、响应头、Cookies 等

输出 status_code 属性得到状态码,输出 headers 属性得到响应头,输出 cookies 属性得到 Cookies,输出 url 属性得到 URL,输出 history 属性得到请求历史。

requests 还提供了一个内置的状态码查询对象 requests.codes

下面列出了返回码和相应的查询条件,方便编程时使用:

# 信息性状态码  
100: ('continue',),  
101: ('switching_protocols',),  
102: ('processing',),  
103: ('checkpoint',),  
122: ('uri_too_long', 'request_uri_too_long'),  # 成功状态码  
200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'),  
201: ('created',),  
202: ('accepted',),  
203: ('non_authoritative_info', 'non_authoritative_information'),  
204: ('no_content',),  
205: ('reset_content', 'reset'),  
206: ('partial_content', 'partial'),  
207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),  
208: ('already_reported',),  
226: ('im_used',),  # 重定向状态码  
300: ('multiple_choices',),  
301: ('moved_permanently', 'moved', '\\o-'),  
302: ('found',),  
303: ('see_other', 'other'),  
304: ('not_modified',),  
305: ('use_proxy',),  
306: ('switch_proxy',),  
307: ('temporary_redirect', 'temporary_moved', 'temporary'),  
308: ('permanent_redirect',  'resume_incomplete', 'resume',), # These 2 to be removed in 3.0  # 客户端错误状态码  
400: ('bad_request', 'bad'),  
401: ('unauthorized',),  
402: ('payment_required', 'payment'),  
403: ('forbidden',),  
404: ('not_found', '-o-'),  
405: ('method_not_allowed', 'not_allowed'),  
406: ('not_acceptable',),  
407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),  
408: ('request_timeout', 'timeout'),  
409: ('conflict',),  
410: ('gone',),  
411: ('length_required',),  
412: ('precondition_failed', 'precondition'),  
413: ('request_entity_too_large',),  
414: ('request_uri_too_large',),  
415: ('unsupported_media_type', 'unsupported_media', 'media_type'),  
416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),  
417: ('expectation_failed',),  
418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),  
421: ('misdirected_request',),  
422: ('unprocessable_entity', 'unprocessable'),  
423: ('locked',),  
424: ('failed_dependency', 'dependency'),  
425: ('unordered_collection', 'unordered'),  
426: ('upgrade_required', 'upgrade'),  
428: ('precondition_required', 'precondition'),  
429: ('too_many_requests', 'too_many'),  
431: ('header_fields_too_large', 'fields_too_large'),  
444: ('no_response', 'none'),  
449: ('retry_with', 'retry'),  
450: ('blocked_by_windows_parental_controls', 'parental_controls'),  
451: ('unavailable_for_legal_reasons', 'legal_reasons'),  
499: ('client_closed_request',),  # 服务端错误状态码  
500: ('internal_server_error', 'server_error', '/o\\', '✗'),  
501: ('not_implemented',),  
502: ('bad_gateway',),  
503: ('service_unavailable', 'unavailable'),  
504: ('gateway_timeout',),  
505: ('http_version_not_supported', 'http_version'),  
506: ('variant_also_negotiates',),  
507: ('insufficient_storage',),  
509: ('bandwidth_limit_exceeded', 'bandwidth'),  
510: ('not_extended',),  
511: ('network_authentication_required', 'network_auth', 'network_authentication')

高级用法

再来了解下 requests 的一些高级用法,如文件上传、Cookies 设置、代理设置等

文件上传

假设上传刚才的图标文件

files = {'file': open('favicon.ico', 'rb')}
r = requests.post('http://httpbin.org/post', files=files)
print(r.text)

http://httpbin.org/post可用来进行文件上传的测试,会返回相应的数据

在这里插入图片描述

Cookies

获取 Cookies 的过程:

r = requests.get('https://www.baidu.com')
print(r.cookies)
for key, value in r.cookies.items():print(key + '=' + value)

首先调用 cookies 属性即可成功得到 Cookies,可以发现它是 RequestCookieJar 类型。然后用 items 方法将其转化为元组组成的列表,遍历输出每一个 Cookie 的名称和值,实现 Cookie 的遍历解析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将自己的cookie添加到请求头中,即可登陆自己的账号。

会话维持

在 requests 中,如果直接利用 get 或 post 等方法的确可以做到模拟网页的请求,但是这实际上是相当于不同的会话,也就是说相当于你用了两个浏览器打开了不同的页面。

第一个请求利用 post 方法登录了某个网站,第二次想获取成功登录后的自己的个人信息,你又用了一次 get 方法去请求个人信息页面。实际上,这相当于打开了两个浏览器,是两个完全不相关的会话,能成功获取个人信息吗?那当然不能。

Session 对象可以方便地维护一个会话,而且不用担心 cookies 的问题,它会帮我们自动处理好

requests.get('http://httpbin.org/cookies/set/number/123456789')
r = requests.get('http://httpbin.org/cookies')

这里我们请求了一个测试网址 http://httpbin.org/cookies/set/number/123456789。请求这个网址时,可以设置一个 cookie,名称叫作 number,内容是 123456789,随后又请求了 http://httpbin.org/cookies,此网址可以获取当前的 Cookies。

运行结果如下:

{“cookies”: {} }

并没有获取到cookie,Cookie 保存在客户端(浏览器),Session 保存在服务器端。

使用session:

s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789')
r = s.get('http://httpbin.org/cookies')
print(r.text)

运行结果:

{
“cookies”: {“number”: “123456789”}
}

SSL证书验证

requests 还提供了证书验证的功能。当发送 HTTP 请求的时候,它会检查 SSL 证书,我们可以使用 verify 参数控制是否检查此证书。其实如果不加 verify 参数的话,默认是 True,会自动验证。

如果请求一个 HTTPS 站点,但是证书验证错误的页面时,就会报SSL错误,将参数设置为False即可:

response = requests.get('https://www.12306.cn', verify=False)

代理设置

对于某些网站,在测试的时候请求几次,能正常获取内容。但是一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出验证码,或者跳转到登录认证页面,更甚者可能会直接封禁客户端的 IP,导致一定时间段内无法访问。

那么,为了防止这种情况发生,我们需要设置代理来解决这个问题,这就需要用到 proxies 参数。可以用这样的方式设置:

import requestsproxies = {'http': 'http://10.10.1.10:3128','https': 'http://10.10.1.10:1080',
}requests.get('https://www.taobao.com', proxies=proxies)

超时设置

在本机网络状况不好或者服务器网络响应太慢甚至无响应时,我们可能会等待特别久的时间才可能收到响应,甚至到最后收不到响应而报错。使用timeout参数计算发出请求到服务器返回响应的时间。请求分为连接读取两个阶段,timeout为这两者的总和。

身份认证

在配置服务器设置或进入一些管理页面,如rabbitmq的管理页面,会需要我们进行身份验证,即输入用户名和密码才能进行配置。此时可以使用 requests 自带的身份认证功能,示例如下:

import requests  
from requests.auth import HTTPBasicAuth  r = requests.get('http://localhost:5000', auth=HTTPBasicAuth('username', 'password'))  
print(r.status_code)

requests 提供了一个更简单的写法,可以直接传一个元组,它会默认使用 HTTPBasicAuth 这个类来认证

r = requests.get('http://localhost:5000', auth=('username', 'password'))

Prepared Request

可以将请求表示为数据结构,其中各个参数都可以通过一个 Request 对象来表示

from requests import Request, Sessionurl = 'http://httpbin.org/post'
data = {'name': 'germey'}
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
}
s = Session()
req = Request('POST', url, data=data, headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)
print(r.text)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/169740.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html web前端,登录,post请求提交 json带参

html web前端&#xff0c;登录&#xff0c;post请求提交 json带参 3ca9855b3fd279fa17d46f01dc652030.jpg <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title></t…

rust学习——方法 Method

文章目录 方法 Method定义方法self、&self 和 &mut self方法名跟结构体字段名相同 带有多个参数的方法关联函数多个 impl 定义为枚举实现方法 rust 结构体与枚举的区别回答1回答2 方法 Method 从面向对象语言过来的同学对于方法肯定不陌生&#xff0c;class 里面就充斥…

Python-----for循环基本语法及其应用---对序列进行遍历循环

for循环基本语法 for循环结构主要用于&#xff08;序列 &#xff1a;包括 字符串、列表、元组、集合以及字典&#xff09;类型数据的遍历&#xff08;循环&#xff09;操作。 遍历(Traversal)&#xff0c;是指沿着某条搜索路线&#xff0c;依次对树&#xff08;或图&#…

nodejs+wasm+rust debug及性能分析

文章目录 背景v8引擎自带的profilelinux的perf采集wasm三方库性能分析编译debug版本wasmrust程序debug调试异常模型正常模型结论优化 参考 Node使用火焰图优化CPU爆涨 - 掘金 【Node.js丨主题周】理解perf 与火焰图-腾讯云开发者社区-腾讯云 Easy profiling for Node.js Applic…

RK3568平台开发系列讲解(应用篇)串口应用编程之串口的使用步骤

🚀返回专栏总目录 文章目录 一、配置参数1.1、获取当前串口的配置参数1.2、修改和写入串口的配置参数二、模式2.1、输入模式2.2、输出模式2.3、控制模式2.4、本地模式2.5、特殊控制字符沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 串口设备是嵌入式开发中最常用的…

Node.js在Python中的应用实例解析

随着互联网的发展&#xff0c;数据爬取成为了获取信息的重要手段。本文将以豆瓣网为案例&#xff0c;通过技术问答的方式&#xff0c;介绍如何使用Node.js在Python中实现数据爬取&#xff0c;并提供详细的实现代码过程。 Node.js是一个基于Chrome V8引擎的JavaScript运行时环境…

Flutter的Invalid use of a private type in a public API警告

文章目录 问题描述有问题的源码 问题原因解决方法 问题描述 自己在写Flutter 应用时发现了一个Invalid use of a private type in a public API警告。 发现很多官方的例子也有这个问题。 有问题的源码 有问题的源码如下&#xff1a; class MyTabPage extends StatefulWid…

【三维重建-PatchMatchNet复现笔记】

【三维重建-PatchMatchNet复现笔记】 1 突出贡献2 数据集描述3 训练PatchMatchNet3.1 输入参数3.2 制定数据集加载方式 1 突出贡献 在计算机GPU和运行时间受限的情况下&#xff0c;PatchMatchNet测试DTU数据集能以较低GPU内存和较低运行时间&#xff0c;整体误差位列中等&#…

python sqlalchemy(ORM)- 02 表关系

文章目录 表关系ORM表示 1v1ORM表示 1vm 表关系 1:1&#xff0c;表A 中的一条记录&#xff0c;仅对应表B中的一条记录&#xff1b;表B的一条记录&#xff0c;仅对应表A的一条记录。1:m&#xff0c;表A中的一条记录&#xff0c;对应表B中的多条记录&#xff0c;表B中的一条记录…

【机器学习】集成学习Boosting

文章目录 集成学习BoostingAdaBoost梯度提升树GBDTXGBoostxgboost库sklearn APIxgboost库xgboost应用 集成学习 集成学习&#xff08;ensemble learning&#xff09;的算法主要包括三大类&#xff1a;装袋法&#xff08;Bagging&#xff09;&#xff0c;提升法&#xff08;Boo…

在 Python 中使用 Pillow 进行图像处理【2/4】

第二部分 一、说明 该文是《在 Python 中使用 Pillow 进行图像处理》的第二部分&#xff0c;主要介绍pil库进行一般性处理&#xff1a;如&#xff1a;图像卷积、钝化、锐化、阈值分割。 二、在 Python 中使用 Pillow 进行图像处理 您已经学习了如何裁剪和旋转图像、调整图像大…

26. 通过 cilium pwru了解网络包的来龙去脉

pwru是一种基于eBPF的工具,可跟踪Linux内核中的网络数据包,并具有先进的过滤功能。它允许对内核状态进行细粒度检查,以便通过调试网络连接问题来解决传统工具(如iptables TRACE或tcpdump)难以解决甚至无法解决的问题。在本文中,我将介绍pwru如何在不必事先了解所有内容的…

【java】【重构二】分模块开发版本锁定以及耦合(打包)实战

目录 一、创建dependencyManagement标签 二、 将需要版本控制的依赖版本进行标签设置 三、将需要版本控制的依赖从各子模块迁移到此处 四、将父模块的依赖版本控制 五、删除子模块的全部版本 1、bocai-web-management模块 2、bocai-utils模块 六、打包 1、确定代码都…

shein面试:nacos无入侵配置,做过吗,怎么做?

说在前面 在40岁老架构师 尼恩的读者社区(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、shein 希音、百度、网易的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 无入侵配置&#xff0c;做过吗&#xff0c;怎么做的&#xff1f;Na…

学习package.json

package.json 文件&#xff0c;它是项目的配置文件&#xff0c;常见的配置有配置项目启动、打包命令&#xff0c;声明依赖包等。package.json 文件是一个 JSON 对象&#xff0c;该对象的每一个成员就是当前项目的一项设置。 {"name": "monorepo_frame",&q…

Go 实现选择排序算法及优化

选择排序 选择排序是一种简单的比较排序算法&#xff0c;它的算法思路是首先从数组中寻找最小&#xff08;大&#xff09;的元素&#xff0c;然后放到数组中的第一位&#xff0c;接下来继续从未排序的元素中寻找最小&#xff08;大&#xff09;元素&#xff0c;然后放到已排序…

Zabbix告警与飞书集成

一、配置媒介 1、下载飞书的Zabbix媒介类型如下&#xff1a; zbx_export_mediatype_feishu.xml 2、Zabbix中导入媒介类型 Zabbix Web中选择管理 > 报警媒介&#xff0c;然后导入该媒介类型。导入规则选择“更新现有的”和“创建新的”。 3、配置飞书媒介类型用户 Zabbi…

【MyBatis进阶】mybatis-config.xml分析以及try-catch新用法

目录 尝试在mybatis项目中书写增删改查 遇见问题&#xff1a;使用mybaties向数据库中插入数据&#xff0c;idea显示插入成功&#xff0c;但是数据库中并没有数据变化? MyBatis核心配置文件剖析 细节剖析&#xff1a; try-catch新用法 截至目前我的项目存在的问题&#xf…

AD20~PCB的板层设计和布线

1、打开51单片机最小系统的工程文件。 2、完成原理图后续工作&#xff1a;打开原理图文件&#xff0c;双击元件“CH340X”窗口右边弹出元件内部属性设置界面&#xff0c;在窗口下方点击“Footprint ->Add…”按钮进入添加元件类型界面&#xff0c;进入元件封装选择界面&…

红日靶场复现1

红日靶场复现1&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f388;&#x1f388;&#x1f389;&#x1f388;&#x1f388;&#x1f389; 一、主机发现&#x1f388;&#x1…