这篇文章主要介绍了Python爬虫原理与基本请求库urllib详解,爬虫就是通过模拟浏览器,按照一定的规则,自动、大批量的获取网络资源,包括文本、图片、链接、音频、视频等等,需要的朋友可以参考下
爬虫的定义:请求网站,并提取数据的自动化程序。
通过模拟浏览器,按照一定的规则,自动、大批量的获取网络资源,包括文本、图片、链接、音频、视频等等。
(讲的就是如何获取网络资源的问题—怎么爬?要有尊严的爬,坐着就把数据优雅的爬下来)
1、发起请求:模拟浏览器向目标站点发送一个request,等待服务器响应;
2、获取响应内容:如果服务器能正常响应,会返回一个response,这便是所要获取的页面内容
3、解析内容:根据自己的需求,通过各种解析方法,将得到的内容进行解析
4、保存数据:存放于数据库或者保存为特定格式的文件
所以接下来本次我们要学习的内容就是以上这四个步骤了。
这个库的作用呢,就是爬虫原理中的第一、二步,向目标网站发送请求用的。
本节内容:
- 用urllib抓取网页的基本语法
- 抓取需要输入关键词的网页
- 抓取需要登录密码的网页
- 抓取反爬机制的网页
- urllib异常处理
有两种方法,一种是直接抓取,一种是直接将目标网址的网页信息保存到本地。
#无论哪种方法,先导包
import urllib.request
'''
urllib.request.urlopen(url, data, timeout) 发送request请求(3个参数不需都写,但必须有url)
url:目标网址
data:访问url时发送的数据包,默认为null
timeout:等待时长
'''
response = urllib.request.urlopen('http://www.baidu.com/')
# decode():解码,将字节流格式数据以相应的形式转化为字符串
print(response.read().decode('utf-8'))
通过urllib请求后得到的response打印如下:
'''
urllib.request.urlretrieve(url,filename) 直接将目标网址的网页信息保存到本地
filename:想保存到的路径文件名
然后用urllib.request.urlcleanup()清除缓存
'''
filename = urllib.request.urlretrieve('http://www.baidu.com/',filename='baidu.html')
urllib.request.urlcleanup()
背景:我想爬取目标网页上支持搜索关键词的网页所有相关信息,比如我想爬百度上所有python的信息,或者疫情的信息,或者其它的信息,如果每次都更换url那就太低效了。 分析网页url:目标网页是百度,//www.baidu.com/,输入python之后url有变化,发现//www.baidu.com/s?wd=python这个网址也能搜索到python的信息,找到规律,//www.baidu.com/s?wd=后面的词可以替换成任何词,都支持搜索,那么我们可以把这个词用input来输入得到,然后对url做一个拼接。 注意:发现//www.baidu.com/s?wd=后面的词不支持中文搜索,原因是网址中都是字节流的数据,所以如果我们要输入中文搜索的话,要将中文转为字节流格式。
# 定义关键词
keyword = input('输入你想查询的关键词:')
# 处理中文,进行编码,转成字节流格式
keyword = urllib.request.quote(keyword)
# url重构
url = 'http://www.baidu.com/s?wd='+keyword
response = urllib.request.urlopen(url).read()
# 保存到本地
f = open('baidu_search.html','wb') #wb存储字节流数据,所以上述response不需要用decode解码
f.write(response)
f.close()
背景:需要爬取用户登录之后页面的数据, 这里有一个url供大家练习://www.iqianyue.com/mypost/ 该网页输入任何用户名和密码都能成功登录,下图为登录后的页面,也就是我们这次通过写程序要爬取的结果页面。
还记得urllib的基本语法吗?里面有3个参数,第二个是data,也就是我们传入的值,这里可以把用户名和密码跟着页面请求一起发送过去,但是要怎么做呢?首先要找到网页代码里是怎么设置用户名和密码的命名的(也就是字典里的key值)。
import urllib.request
import urllib.parse #上传用户名和密码,需要先用parse模块进行编码处理
url = 'https://www.iqianyue.com/mypost/'
# urlencode():将上传的数据进行编码处理
# encode():将字符串转化为相应编码的字节流数据
postdata = urllib.parse.urlencode({
'name':'vicky',
'pass':'12345'
}).encode('utf-8')
response = urllib.request.urlopen(url,data=postdata).read()
# 保存网页
f = open('post.html','wb')
f.write(response)
f.close()
运行成功后将post.html文件打开,鼠标点进去后右上角会显示各种浏览器,选择各自使用的浏览器打开页面,就会发现,出现的页面就是登录成功后的页面,跟上图一致。
背景:通过上述常规方法,可以模拟登录页面抓取该目标页面的资源,但也存在一种情况,这一步执行成功后,后续如果想抓取该网站的其它网页,用程序登录进去之后依然是无登录状态,浏览器并没有留下cookie。
【举个栗子】:
import urllib.request
import urllib.parse
# 主页面:'http://blog.chinaunix.net/'
# 登录页面:'http://account.chinaunix.net/login?url=http%3a%2f%2fblog.chinaunix.net'
# 登录跳转页面:'http://account.chinaunix.net/login/sso?url=http%3A%2F%2Fblog.chinaunix.net'
url = 'http://account.chinaunix.net/login/sso?url=http%3A%2F%2Fblog.chinaunix.net'
postdata = urllib.parse.urlencode({
'username':'***',
'password':'******'
}).encode('utf-8')
response = urllib.request.urlopen(url,postdata).read()
f = open('chinaunix.html','wb')
f.write(response)
f.close()
拿这个网站举例,我选的url是登录跳转时的页面,顺利跳转后就进入到首页,如果我后续再写一个请求,直接访问该首页,登录进去发现还是无登录状态。 那么那么那么那么那么…
解决方案;
1、导入cookie处理模块 http.cookiejar
2、使用http.cookiejar.CookieJar()创建cookiejar对象
3、使用HTTPCookieProcessor创建cookie处理器,并以此为参数构建opener对象
4、加载为全局默认的opener
这样写,就把cookie贯穿整个网站的始终了,访问哪个页面都是登录状态。
import urllib.request
import urllib.parse
import http.cookiejar
url = 'http://account.chinaunix.net/login/sso?url=http%3A%2F%2Fblog.chinaunix.net'
postdata = urllib.parse.urlencode({
'username':'***',
'password':'***'
}).encode('utf-8')
response = urllib.request.urlopen(url,postdata).read()
# 创建cookiejar对象
cjar = http.cookiejar.CookieJar()
# 创建cookie处理器,并以此为参数构建opener对象
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar))
# 加载为全局默认的opener
urllib.request.install_opener(opener)
f = open('chinaunix_2.html','wb')
f.write(response)
f.close()
背景:因为有些网站也有一些反爬机制,所以你用上述语法进行常规的发送请求之后不一定能得到响应,,下面就讲述遇到反爬的网站我们应该怎么做。
对于反爬网页的对策有2点: headers:设置头部信息,将爬虫伪装成浏览器 proxy:设置代理,使用代理服务器并经常切换代理服务器
— headers信息也在网页源代码中,找到User-Agent(headers里一般设置这个就行了),构建字典,把:后面的系统浏览器版本等信息全部复制粘贴进来,模拟浏览器登录。
— 发送请求前,要先构建一个Request请求对象,设置headers,再把请求对象传到urlopen中
import urllib.request
url = 'http://t.dianping.com/hangzhou'
# 构建headers
h = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
# 构建Request请求对象
request = urllib.request.Request(url=url, headers=h)
response = urllib.request.urlopen(request).read()
# 保存文件
f = open('headers.html','wb')
f.write(response)
f.close()
也就是代理IP,在一定时间内频繁爬取某个网页可能会被封,所以可以使用一些代理IP来爬取资源。
import urllib.request
def use_Proxy(proxy_addr,url):
# ProxyHandler()设置对应的代理服务器信息
proxy = urllib.request.ProxyHandler({'http':proxy_addr})
# build_opener()创建一个自定义的opener对象
opener = urllib.request.build_opener(proxy)
# 将opener加载为全局使用的opener
urllib.request.install_opener(opener)
response = urllib.request.urlopen(url).read().decode('utf-8')
return response
proxy_addr = '183.146.213.157:80' # IP地址:端口号 自行百度“代理IP”
url = 'http://www.taobao.com'
print(len(use_Proxy(proxy_addr,url))) #随便打印一个长度,看看这个代理IP能否使用
建立异常处理机制,反馈出错原因。
import urllib.request
import urllib.error
try:
response = urllib.request.urlopen('http://www.ijinqian.com')
except urllib.error.URLError as e:
print('发生异常--->'+str(e))
到此这篇关于Python爬虫原理与基本请求库urllib详解的文章就介绍到这了