网页抓取解密(常用的获取网页数据的方式2.1URLlib:未经本人允许,禁止转载! )

优采云 发布时间: 2022-02-12 21:09

  网页抓取解密(常用的获取网页数据的方式2.1URLlib:未经本人允许,禁止转载!

)

  大家好,我不温不火,我是计算机学院大数据专业的三年级学生。我的绰号来自成语——不冷不热,意思是希望我有一个温柔的气质。博主作为互联网行业的新手,写博客一方面是为了记录自己的学习过程,另一方面是总结自己的错误,希望能帮助很多和自己一样处于起步阶段的新人。不过由于水平有限,博客难免会出现一些错误。如果有任何错误,请给我您的建议!暂时只在csdn平台更新,博客主页:.

  PS:由于越来越多的人未经本人同意直接爬博主文章,博主特此声明:未经本人允许,禁止转载!!!

  内容

  

  前言

  网络爬虫的一般流程

  

  一、理解 URL

  基本 URL 收录以下内容:

  模式(或协议)、服务器名称(或IP地址)、路径和文件名,如“protocol://authorization/path?query”。带有授权部分的完整 URI 语法如下所示:protocol://username:password@subdomain。域名。顶级域名:端口号/目录/文件名.filesuffix?parameter=value#sign。

  例如:

  

  二、获取网页数据的常用方法2.1 URLlib

  这里我们先看一个小demo

  # 百度首页

import urllib.request

response = urllib.request.urlopen("http://www.baidu.com")

html = response.read().decode("utf-8")

print(html)

  

  2.2、urllib.request

  官方文档(有兴趣可以自己查看):

  

  1、urllib.request.urlopen

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

  timeout:释放链接的超时时间

  cafile/capath/cadefault:CA认证参数,用于HTTPS协议

  上下文:SSL 链接选项,用于 HTTPS

  2、urllib.request.Request

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

  代码详情:

  

  # coding=utf-8

from urllib import request

from urllib.parse import urlparse

url = "http://httpbin.org/post"

headers = {

"user-agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0'

}

dict = {"name":"buwenbuhuo"}

data = bytes(urllib.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"))

  3、urllib.request 的高级特性

  urllib.request 几乎可以在任何 HTTP 请求中执行所有操作:

  4、开瓶器

  开场导演:

  5、cookies

  

  示例:获取百度 Cookie

  import http.cookiejar,urllib.request

cookie = 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)

  filename = 'cookie.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)

  2.3、请求库

  Requests 是基于 urllib 的 python 编写的,使用 Apache2 Licensed 开源协议的 HTTP 库。Requests 相比 urllib 更方便,可以为我们省去很多工作。建议爬虫使用 Requests 库。

  官方文档链接:

  1、请求库安装

  在终端中运行以下命令: pip install requests

  2、使用requests发起请求

  import requests

import json

# 用requests发起简单的GET请求

url_get = 'http://httpbin.org/get'

response = requests.get(url_get,timeout = 5)

print(json.loads(response.text)['args'])

# 用requests发起带参数的GET请求

kvs = {'k1':'v1','k2':'v2'}

response = requests.get(url_get,params=kvs,timeout = 5)

print(json.loads(response.text)['args'])

# 用requests 发起POST 请求

url_post = 'http://httpbin.org/post'

kvs = {'k1':'v1','k2':'v2'}

response = requests.post(url_post,data=kvs,timeout = 5)

print(response.json()['form'])

  

  从上图中我们可以看出,方法名很清楚的表达了发起的请求,get就是GET,post就是POST。不仅如此,我们的response非常强大,可以直接获取很多信息,而且response中的内容不是一次性的,requests会自动读取response的内容并保存在text变量中,读取你想要多少次。接下来,让我们看看响应中有哪些有用的信息:

  print(response.url)

print(response.status_code)

print(response.headers)

print(response.cookies)

print(response.encoding) # requests会自动猜测响应内容的编码

import json

print(response.json() == json.loads(response.text)) # response.text 是响应内容,可以读取任意次,并且requests可以自动转换json

requests = response.request # 可以直接获取response对应的request

print(response.url)

print(response.headers) # 我们发起的request 是什么样子的一目了然

  

  除了上述信息之外,响应中还提供了很多其他信息。另外,请求除了get和post之外,还提供了显式的put、delete、head、options方法,对应着相应的HTTP方法。有兴趣的读者可以进一步探索。

  3、Requests 库发起 POST 请求

  这部分摘自官方文档:

  通常,如果您希望发送一些表单编码的数据 - 非常类似于 HTML 表单。为此,只需将字典传递给 data 参数。发出请求后,您的数据字典将自动进行表单编码:

  >>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.post("https://httpbin.org/post", data=payload)

>>> print(r.text)

{

...

"form": {

"key2": "value2",

"key1": "value1"

},

...

}

  data参数也可以对每个key有多个值。这可以通过创建数据元组列表或列表值字典来完成。当表单有多个使用相同键的元素时,这尤其有用:

  import requests

>>> payload_tuples = [('key1', 'value1'), ('key1', 'value2')]

>>> r1 = requests.post('https://httpbin.org/post', data=payload_tuples)

>>> payload_dict = {'key1': ['value1', 'value2']}

>>> r2 = requests.post('https://httpbin.org/post', data=payload_dict)

>>> print(r1.text)

{

...

"form": {

"key1": [

"value1",

"value2"

]

},

...

}

>>> r1.text == r2.text

True

  4、requests.Session

  import requests

# 创建一个session对象

s = requests.Session()

# 用session对象发出get请求,设置cookies

s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')

# 用session对象发出另外一个get请求,获取cookies

r = s.get('https://httpbin.org/cookies')

# 显示结果

print(r.text)

  

  请求的大部分用法与 urllib2 类似。此外,请求的文档非常完整。这里主要讲解request最强大、最常用的功能:会话持久化。在上面的代码中,我们连续发起的两个请求是不相关的,这会导致一些数据不可用。喜欢:

  import requests

url_cookies = 'http://httpbin.org/cookies'

url_set_cookies = 'http://httpbin.org/cookies/set?k1=v1&k2=v2'

print(requests.get(url_cookies,timeout = 5).json())

print(requests.get(url_set_cookies,timeout = 5).json())

print(requests.get(url_cookies,timeout = 5).json())

  

  可以看到,调用url_set_cookies设置cookie前后发起的GET请求获取的cookie都是空的。这意味着不同请求之间没有关系。有些人可能会对上面代码中第 5 行的输出感到惊讶,因为在上一篇 文章 我们用 urllib2 发出同样的请求时,结果仍然是空的。这确实有点奇怪,因为 urllib2 默认忽略所有请求的 cookie,即使是重定向请求,并且请求会在请求中保存 cookie(url_set_cookies 请求收录重定向请求)。

  以下代码可以在一个会话中保留多个请求:

  session = requests.Session()

print(requests.get(url_cookies,timeout = 5).json())

print(requests.get(url_set_cookies,timeout = 5).json())

print(requests.get(url_cookies,timeout = 5).json())

  

  我们现在可以看到我们的第三个请求收录了第二个请求设置的 cookie!是不是很简单。其实cookielib也是用来把cookie保存在request里面的,有兴趣的同学可以深入探索一下。

  请求库的特点:

  6、设置代理

  import requests

url = 'http://httpbin.org/cookies/set?k1=v1&k2=v2'

proxies = {'http':'http://username:password@host:port','http://username:password@host:port'}

print(requests.get(url,proxies = proxies,timeout = 5).json()['args'])

# 上面的方法要给每个请求都要加上proxies参数,比较繁琐,可以为每个session设置一个默认的proxies

session = requests.Session()

session.proxies = proxies # 一个session中的所有请求都使用同一套代理

print(session.get(url,timeout = 5).json()['args'])

  上面的代码当然不会工作,因为代理格式不正确。当我们需要它时,我们可以直接重用这段代码。你可能会认为之前所有使用 urllib2 的练习都是徒劳的,因为请求非常容易学习!当然没有白费,urllib2是一个很基础的网络库,其他很多网络库,包括request都是基于urllib2开发的。前面的练习将帮助我们更好地理解网络,了解Python是如何处理网络的,这对我们以后开发可靠高效的爬虫大有裨益。

  必须注意的是:

  响应中的内容以 unicode 编码。为了方便阅读,我们需要将其转换成中文。直接打印是不行的,因为Python在将dict转成字符串时保留了unicide编码,所以直接打印不是中文。

  这里我们使用另一种转换方式:先将得到的表单dict转换成unicode字符串(注意ensure_ascii=False参数,表示unicode字符不转义),再将得到的unicode字符串编码成UTF-8字符串,最后转换为 dict 以便于输出。

  三、浏览器简介

  Chrome 提供了一种检查网页元素的功能,称为 Chrome Inspect。该功能可以在网页上右击查看,如下图所示:

  

  在这个页面调出 Chrome Inspect,我们可以看到类似下面的界面:

  

  通常我们最常用的功能是查看一个元素的源代码。单击左上角的元素定位器可以选择网页中的不同元素。HTML源代码区会自动显示指定元素的源代码,通常CSS显示区也会显示这个应用于元素的样式。Chrome Inspect 比较常用的功能是监控网络交互过程。在功能栏中选择Network,可以看到如下界面:

  

  Chrome 网络的交互区域展示了一个网页加载过程,浏览器发出的所有请求。选择一个请求,右侧会显示该请求的详细信息,包括请求头、响应头、响应内容等。Chrome Network是我们研究网页交互流程的重要工具。Cookie 和会话是重要的网络技术。您还可以在 Chrome Inspect 中查看网络 cookie。在功能栏中选择应用程序,看到如下界面:

  

  在Chrome应用左侧选择Cookies,可以看到以KV形式保存的cookies。当我们研究网页的登录过程时,这个功能非常有用。需要注意的是,在研究一个完整的网络交互过程之前,记得右键点击Cookies,点击清除,清除所有旧的Cookies。

  HTTP 响应的第一行,即状态行,收录状态代码。状态码由三位数字组成,表示服务器对客户端请求的处理结果。状态码分为以下几类:

  1xx :信息响应类,表示收到请求,继续处理

  2xx:处理成功响应类,表示动作成功接收、理解、响应

  3xx : 重定向响应类,必须做进一步处理才能完成指定动作

  4xx:客户端错误,客户端请求收录语法错误或服务器无法理解

  5xx:服务器错误,服务器无法正确执行有效请求

  以下是一些常见的状态码及其说明:

  200 OK:请求已被处理并正确响应。

  301 Move Permanently:永久重定向。

  302 临时移动:临时重定向。

  400 Bad Request:服务器不理解请求。

  401 Authentication Required :需要用户验证。

  403 Forbidden:禁止访问资源。

  404 Not Found:找不到资源。

  405 Method Not Allowed:资源使用了错误的方法,例如应该使用POST,但使用了PUT。

  408 Request Timeout :请求超时。

  500 内部服务器错误:内部服务器错误。

  501 Method Not Implemented:请求方法无效,如果可能,将GET写成Get。

  502 Bad Gateway : 网关或代理收到上游服务器的错误响应。

  503 Service Unavailable :服务暂时不可用,您可以稍后尝试。

  504 Gateway Timeout:网关或代理对上游服务器的请求超时。

  在实际应用中,大部分网站都有反爬策略,响应状态码代表服务器的处理结果,是我们调整爬取状态(如频率、ip)的重要参考履带式。比如我们一直正常运行的爬虫突然得到403响应,很可能是服务器识别到了我们的爬虫,拒绝了我们的请求。这时候我们就需要放慢爬取频率,或者重启会话,甚至更换IP。

  

  美好的日子总是短暂的。虽然我想继续和你聊天,但是这篇博文已经结束了。如果还不够好玩,别着急,我们下期再见!

  

  一本好书读一百遍也不厌烦,熟了课才知道自己。而如果我想成为观众中最漂亮的男孩,我必须坚持通过学习获得更多的知识,用知识改变命运,用博客见证我的成长,用行动证明我在努力。

  如果我的博客对你有帮助,如果你喜欢我的博客内容,请一键“点赞”“评论”“采集”!听说喜欢的人不会倒霉的,每天都精神抖擞!如果你真的想白嫖,那么祝你天天快乐,也欢迎经常光顾我的博客。

  码字不易,大家的支持是我坚持下去的动力。喜欢后别忘了关注我哦!

  

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线