二、学习分布式爬虫之urllib库

urllib库(python自带)

urllib库是python中一个基本的网络请求库,可以模拟浏览器行为,向指定的服务器发送请求,并可以保存服务器返回的数据。
python3的urllib库中所有和网络请求相关的方法,都被集到urllib.request模块中

urlopen函数

创建一个表示远程url的类文件对象,然后像本地文件一样操作这个类文件对象来获取远程数据。(浏览器打开网址)

  1. url:请求的网址
  2. data:请求的数据,如果设置了这个值,那么将变成post请求。
  3. 返回值:返回值是一个<http.client.HTTPResponse object at 0x0338FDC0>对象,有read(size),readline(),readlines()以及getcode()(获取状态码)等方法。
from urllib import request
resp = request.urlopen('https://www.sogou.com/')
print(resp.read())

urlretrieve函数

这个函数可以方便的将网页上的一个文件保存到本地

from urllib import request
request.urlretrieve('https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1449833412,3131219507&fm=26&gp=0.jpg','周杰伦.jpg')

urlencode函数

可以把字典数据转换为URL编码的数据

from urllib import parse
data = {'name':'周杰伦','age':'30','greet':'hello world'}
res = parse.urlencode(data) #编码
print(res)# name=%E5%91%A8%E6%9D%B0%E4%BC%A6&age=30&greet=hello+world
res_de=parse.parse_qs(res) #解码
print(res_de)
#{'name': ['周杰伦'], 'age': ['30'], 'greet': ['hello world']}

parse.quote():可以对字符串进行编码

url解析

有时候拿到一个url,想要对这个url中的各个组成部分进行分割,就可以使用urlparse和urlsplit函数。
两个函数基本上是一样的,唯一不一样的地方就是urlparse里有params属性,而urlsplit没有。

from urllib import parse
res = parse.urlparse('http://www.baidu.com/index.html;user?id=s#comment')
#ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=s', fragment='comment')
print(res)
print(res.scheme)
print(res.netloc)
print(res.path)
from urllib import parse
res = parse.urlsplit('http://www.baidu.com/index.html;user?id=s#comment')
#SplitResult(scheme='http', netloc='www.baidu.com', path='/index.html;user', query='id=s', fragment='comment')
print(res)
print(res.scheme)
print(res.netloc)
print(res.path)

request.Request类:网络请求,可以增加请求头

from urllib import request
header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36'
}
res = request.Request('https://www.baidu.com/',headers=header)
resp = request.urlopen(res)
print(resp.read())

proxyHandler处理器(代理设置):解决封IP问题

很多网站会检测某段时间某个IP的访问次数(通过流量统计、系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问。
http://httpbin.org 查看http请求的一些参数。
常用的代理

  1. 西刺免费代理IP:http://www.xicidaili.com/
  2. 快代理:http://www.kuaidaili.com/
  3. 代理云:http://www.dailiyun.com/
from urllib import request
# #不使用代理
# url = 'http://httpbin.org/ip'
# resp = request.urlopen(url)
# print(resp.read())

#使用代理
#步骤
url = 'http://httpbin.org/ip'
#1.使用proxyHandler,传入代理构建一个handler
handler = request.ProxyHandler({'http':'115.216.56.155:9999'})
#2.使用上面的handler构建一个opener
opener = request.build_opener(handler)
#3.使用opener发送一个请求
resp = opener.open(url)
print(resp.read())

什么是cookie

指某些网站为了辨别用户身份进行session跟踪而储存在用户本都终端上的数据,cookie储存的数量有限,一般不超过4KB,因此cookie只能储存小量的数据。
cookie的格式
Set-cookie:NAME=VALUE;Expires/Max-age=DATE;Path=PATH;
Domain=DOMAIN_NAME;SECURE
参数的意义
NAME:cookie的名字
VALUE:cookie的值
Expires:cookie的过期时间
Path:cookie作用的路径
Domain:cookie作用的域名
SECURE:是否只在https协议下起作用

知乎登录模拟实战1

from urllib import request
url = 'https://www.zhihu.com/'
header = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36',
    #添加cookie
    'cookie': '_zap=d787f891-928e-4802-a36f-f932fbce85cc; _xsrf=T4pgZdazbwlWX70ktyxjai6mBHqt2Tee; d_c0="ADAXHRmRyhCPTnOLCXOeSw2YPn2xT_iZvq8=|1581251934"; capsion_ticket="2|1:0|10:1581251957|14:capsion_ticket|44:Njg1OTQxMWQ5YzkzNGEzMThlMjRiYzA3YjlhYWE3Y2I=|5b514ab39e5c847c527eb6d6967cfa29a2dc1cab5056f490d155c25c78b79c90"; z_c0="2|1:0|10:1581251999|4:z_c0|92:Mi4xTmd6VkNnQUFBQUFBTUJjZEdaSEtFQ1lBQUFCZ0FsVk5uMHN0WHdCOGs3MmZOTkdfT21lRVlCSUQwY1V6cFN5N09n|3cc13f09f49f1de5535017656d99fe7f4ce2ca4dc239911a9ac866f7f2110f8d"; unlock_ticket="APDltcvN3A0mAAAAYAJVTacEQF4avQyXNCvlitZvRoXJOoaaF1rJ0g=="; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1581252005; tst=r; KLBRSID=4843ceb2c0de43091e0ff7c22eadca8c|1581252069|1581251924; Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49=1581252069'
}
resp = request.Request(url,headers=header)
res = request.urlopen(resp)
print(res.read().decode('utf-8'))

http.cookiejar模块

该模块主要的类有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。作用分别如下:

  1. CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。
  2. FileCookieJar(filename,delayload=None,policy=None):从CookieJar派生而来。用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问文件,即只有在需要时才读取文件或在文件中存储数据。
  3. MozillaCookieJar(filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与Mozilla(火狐)浏览器cookie.txt兼容的FileCookieJar实例。
  4. LWPCookieJar(filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与libwww-perl标准的Set-Cookie3文件格式兼容的FileCookieJar实例。

美食杰模拟登录爬取个人网页信息

from urllib import request
from urllib import parse
from http.cookiejar import CookieJar

#登录的网页 https://i.meishi.cc/login.php
#个人网页  https://i.meishi.cc/cook.php?id=14417636

#1.登录
#1.1  创建cookiejar对象
cookiejar = CookieJar()
#1.2  使用cookiejar对象创建一个HTTPCookieProcess对象
handler = request.HTTPCookieProcessor(cookiejar)
#1.3  使用上一步创建的handler创建一个opener
opener = request.build_opener(handler)
#1.4  使用opener发送登录请求  (需要账号和密码)
post_url = 'https://i.meishi.cc/login.php'
post_data = parse.urlencode({
    'username':'1579795****',
    'password':'****'
})#需要对账户和密码进行url编码
req = request.Request(post_url,data=post_data.encode('utf-8'))  #获得一个urllib.request.Request object
opener.open(req) #运行后opener会拥有登录所需要的cookie

#2. 访问个人网页
header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36'
}
url = 'https://i.meishi.cc/cook.php?id=14417636'
rq = request.Request(url,headers=header)
res = opener.open(rq) #此时opener已经拥有登录所需要的cookie
print(res.read().decode('utf-8'))

cookie的保存与加载

from urllib import request
from http.cookiejar import MozillaCookieJar

#将cookie保存到本地
cookiejar = MozillaCookieJar('cookie.txt')
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
res = opener.open('http://www.baidu.com')
cookiejar.save(ignore_discard=True,ignore_expires=True)
#ignore_discard当cookie即将过期,False不将它保存,True则仍保存
#ignore_expires当cookie已经过期,False不将它保存,True则仍保存

#加载cookie
cookiejar = MozillaCookieJar('cookie.txt')
cookiejar.load()
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
res = opener.open('http://www.baidu.com')
for cookie in cookiejar:
    print(cookie)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章