失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 利用python爬虫(part1)--urllib.request模块

利用python爬虫(part1)--urllib.request模块

时间:2023-10-15 16:30:01

相关推荐

利用python爬虫(part1)--urllib.request模块

学习笔记

文章目录

网络爬虫概述定义爬虫分类爬取数据步骤爬虫请求模块常用方法urllib.request.urlopen()方法响应对象(response)方法关于请求头urllib.request.Request()

网络爬虫概述

定义

其实就是用Python程序模仿人点击浏览器并访问网站,而且模仿的越逼真越好。

爬虫分类

①通用网络爬虫(搜索引擎使用,需要遵守robots协议)

robots协议 :网站通过robots协议,告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

比如:/robots.txt

根据CSDN的robots协议,对于所有的爬虫用户,Disallow后的内容是不可以爬取的。

②聚焦网络爬虫 :自己写的爬虫程序(可以不遵守robots协议)

爬取数据步骤

①确定需要爬取的URL地址

②由请求模块向URL地址发出请求,并得到网站的响应

③从响应内容中提取所需数据

- 提取所需数据,并保存

- 页面中有其他需要继续跟进的URL地址,回到第2步发起请求,如此循环

爬虫请求模块

模块

urllib.request

常用方法

urllib.request.urlopen()方法

作用

向网站发起请求,并获取响应对象

语法

urllib.request.urlopen(url, timeout)#URL:需要爬取的URL地址#timeout: 设置等待超时时间,指定时间内未得到响应,则抛出超时异常

响应对象(response)方法

#获取响应对象的内容bytes = response.read()string = response.read().decode('utf-8')# 返回实际数据的URL地址url = response.geturl()# HTTP响应码(比如:200/404等)code = response.getcode()#编码string.encode() # string -> bytes#解码bytes.decode() # bytes -> string

下面,我们先举一个例子,来了解一下网爬的流程。

举个例子

首先,我们向微博(/)发起请求,并得到微博的响应对象:

#导入请求模块import urllib.request#向微博发起请求(注意:地址要写全),得到响应对象response = urllib.request.urlopen('/')print(response)

结果:

<http.client.HTTPResponse object at 0x000000EA0B11EBA8>

备注:在python中发起请求时,网站地址要写全。

平时我们写的网址,就是URL地址

URL协议规定了URL地址的格式。

URL地址举例:/c/zg/-10-27/doc-ifxizwsm2427861.shtml

URL协议规定格式:scheme://host.domain:port/path/filenamescheme - 定义因特网服务的类型。最常见的类型是 http, https,ftphost - 定义域主机(http 的默认主机是 www) domain - 定义因特网域名,比如port - 定义主机上的端口号(http 的默认端口号是 80) path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。 filename - 定义文档/资源的名称

获取响应对象的内容(网页源代码):

wangye = response.read()print(wangye)

部分结果:

我们得到的是byte数据类型的网页源代码。

我们再以utf-8编码形式对byte数据类型的网页源代码进行解码,得到字符串类型的网页源代码:

wangye = response.read().decode('utf-8')print(wangye)

结果:

UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xca in position 339: invalid continuation byte

报错!发生了UnicodeDecodeError错误。

原因可能是新浪的网页源代码中使用了中文字符。故我们改用gbk编码格式,进行解码:

wangye = response.read().decode('gbk')print(wangye)

部分结果:

返回获取数据的URL地址和HTTP响应码:

url = response.geturl()code = response.getcode()print(url)print(code)

结果:

/visitor/visitor?entry=miniblog&a=enter&url=https%3A%2F%%2F&domain=.&ua=php-sso_sdk_client-0.6.28&_rand=1585717972.5771响应码: 200

关于请求头

在我们向一个网站发起请求时,一定会发送请求头。当网站收到我们的请求时,首先会检查我们请求头中User-Agent。 如果我们用浏览器发起请求,则此时,User-Agent中会有操作系统、浏览器版本、内核等信息;但是如果我们用程序发起请求,并且没有设置请求头,则此时User-Agent会显得”不正常”,故网站会很容易的发现我们是通过爬虫访问的,而不是正常的浏览器访问。

我们利用一个测试网站(/get, 当我们向这个网站发起请求时,网站会返回我们的请求头)做一个小测试:

我们先用Chrome浏览器,访问这个测试网站,这个网站会返回给我们如下请求头:

{"args": {}, "headers": {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Host": "", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-5e8426bf-69a4172ea646d941270576d5"}, "origin": "114.105.135.48", "url": "/get"}

可以看到,我们通过Chrome浏览器进行请求的User-Agent为Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36。

我们再用程序访问,代码如下:

#导入请求模块import urllib.request#向微博发起请求(注意:地址要写全),得到响应对象response = urllib.request.urlopen('/get')#print(response)wangye = response.read().decode('utf-8')print(wangye)

结果:

{"args": {}, "headers": {"Accept-Encoding": "identity", "Host": "", "User-Agent": "Python-urllib/3.6", "X-Amzn-Trace-Id": "Root=1-5e8426f1-ca27dd62e83b367c4715d4a0"}, "origin": "114.105.135.48", "url": "/get"}

可以看到,我们通过程序访问的User-Agent为:“Python-urllib/3.6”,这显然不是正常浏览器的User-Agent,一般的网页如果看到这样的User-Agent,会直接把我们的请求枪毙。

所以这时,我们要自己包装一个请求头,伪装成正常的浏览器,欺骗网页进行访问。可惜的是,我们的urlopen()方法并不支持包装请求头,我们需要学习新的内容对请求头进行包装。

urllib.request.Request()

作用

创建请求对象(包装请求,重构User-Agent,使程序更像正常人类请求,避免网站反爬)

注意这里只是创建请求对象,并没有发起请求。

语法

urllib.request.Request(url, headers)# url:请求的URL地址 #headers:添加请求头(爬虫和反爬虫斗争的第一步)

使用流程

#1.构造请求对象(重构User-Agent)req = urllib.request.Request(url=url,headers={'User-Agent':'Mozilla/5.0 xxxx'})#2.发请求获取响应对象(urlopen)res = urllib.request.urlopen(req)#3.获取响应对象内容html = res.read().decode('utf-8')

举个例子

向测试网站/get发起请求,构造请求头,并检查响应对象内容:

import urllib.requesturl = '/get'headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0)'}#User-Agent可以自己在网上随便找req = urllib.request.Request(url = url, headers = headers)response = urllib.request.urlopen(req)print(response.read().decode('utf-8'))

网站返回的请求头:

{"args": {}, "headers": {"Accept-Encoding": "identity", "Host": "", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0)", "X-Amzn-Trace-Id": "Root=1-5e86b85a-3d13d9b784ee0ef05416b377"}, "origin": "183.164.105.16", "url": "/get"}

可以看到,我们的User-Agent已经改变了。初步伪装成功!

如果觉得《利用python爬虫(part1)--urllib.request模块》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。