Urllb 库是 Pythn 中一个最基本的网络请求库。可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据。
-
urlopen 函数:
在 Python 的 urllib 库中,所有和网络请求相关的方法,都被集到 urllib.request 模块下面。
urtopen 函数的基本使用:
from urllib import request
resp = request.urlopen('http://www.baidu.com')
print(resp.read())
实际上,使用浏览器访问百度,右键查看源代码。你会发现,跟我们刚才打印出来的数据是一模一样的。也就是说,上面的三行代码就已经帮我们把百度的首页的全部代码爬下来了。一个基本的 url 请求对应的python代码真的非常简单。
以下对 urlopen 函数进行详细的讲解:
-
url :请求的url。
-
date:请求的date,如果设置了这个值,那么将变成 post 请求。
-
返回值:返回值是一个 http.client.HTTPResponse 对象,这个对象是一个类文件句柄对象。有 read(size)、readline 、readlines 以及 getcode 等方法。
# 练习 from urllib import request import pprint # print()函数可以实现输出,可以输出字符串、数值、列表、字典等;而pprint模块,可以提供打印出任何python数据结构类和方法。 resp = request.urlopen('http://www.baidu.com') pprint.pprint(resp.read()) # 读出全部数据 print(resp.readline()) # 读取第一行数据 print(resp.readlines(20)) # 读取多行数据 print(resp.getcode()) # 获取响应的状态
-
urlretrieve 函数:
-
这个函数可以方便的将网页上的一个文件保存到本地。以下代码可以非常方便的将百度的首页下载到本地:
from urllib import request request.urlretrieve('http://www.baidu.com/','baidu.html')
-
-
urlencode 函数:
-
用浏览器发送请求的时候,如果url中包含了中文或者其他特殊字符,那么浏览器会自动的给我们进行编码。而如果使用代码发送请求,那么就必须手动进行编码,这时候就应该使用 urlencode 函数来实现。 urlencode 可以把字典数据转换为 URL 编码的数据。
-实例代码:
from urllib import parse data = {'name';'爬虫基础','greet';'hello world','age':100} qs = parse.urlencode(date) print(qs)
urlencode函数相关练习: # urlencode 函数的用法 ''' urlencode函数可以把字典数据转换为URL编码额数据 ''' from urllib import parse from urllib import request result={'name':'爬虫基础','greet':'hello world','age':100} qs = parse.urlencode(result) print(qs) # 打印输出:name=%E7%88%AC%E8%99%AB%E5%9F%BA%E7%A1%80&greet=hello+world&age=100 url = 'http://www.baidu.com/s' #http://www.baidu.com/swd?刘德华 params = {'wd':'刘德华'} qs1 = parse.urlencode(params) # 将刘德华字典数据转换为URL编码数据 url1 = url + "?" + qs1 # 拼接在一起 print(url1) # 打印出完整的连接地址 resp = request.urlopen(url1) # 获取网页的数据 print(resp.read())
-
-
parse_qs函数:
-
可以将经过编码后的url参数进行解码。
-实例代码如下:form urllib import parse qs = "" print(parse.parse_qs(qs))
-
```python
相关练习:
# parse_qs函数的用法:
result={'name':'爬虫基础','greet':'hello world','age':100}
qs = parse.urlencode(result) # 先将字典数据进行编码
print(qs) # 输出:name=%E7%88%AC%E8%99%AB%E5%9F%BA%E7%A1%80&greet=hello+world&age=100
result = parse.parse_qs(qs) # 将编码数据转换为字典数据
print(result) # 输出:{'name': ['爬虫基础'], 'greet': ['hello world'], 'age': ['100']}
- urlparse和urlsplit:
- 有时候拿到一个url,想要对这个url中的各个组成部分进行分割,那么这时候就可以使用urlparse 或者是 urlsplit 来进行分割。
实例代码:
# urlparse 和 urlsplit函数的用法:
from urllib import parse
url = 'http://www.baidu.com/s?wd=python&username=abc#1'
result1 = parse.urlparse(url)
print(result1)
# 输出:ParseResult(scheme='http', netloc='www.baidu.com', path='/s', params='', query='wd=python&username=abc', fragment='1')
result2 = parse.urlsplit(url)
print(result2)
# 输出:SplitResult(scheme='http', netloc='www.baidu.com', path='/s', query='wd=python&username=abc', fragment='1')
print('scheme:',result1.scheme) # scheme: http
print('netloc:',result1.netloc) # netloc: www.baidu.com
print('path:',result1.path) # path: /s
print('params:',result1.query) # params: wd=python&username=abc
print('fragment:',result1.fragment) # fragment: 1
urlparse 和 urlsplit 基本上是一模一样的。唯一不一样的地方是:'urlparse'里面多了一个'params'属性,而'urlsplit'没有'params'这个属性,url中的'parame'属性用的也比较少。
-
request.Request类:
-
如果要在请求的时候增加一些请求头,那么就必须使用 request.Request 类来实现。比如要增加一个User-Agent,实例代码如下:
from urllib import request headers = { 'User-Agent': }''' request.Request类: 如果要在请求的时候增加一些请求头,那么就必须使用 request.Request 类来实现。比如要增加一个User-Agent,实例代码如下: ''' from urllib import request url = 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=' # resp = request.urlopen(url) # print(resp.read()) headers = { 'User-Agest':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36' } resp = request.Request(url,headers=headers) qs = request.urlopen(resp) print(qs.read())
-
**爬虫练习:豆瓣
proxyHandler处理器(代理设置)
很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问。所以我们可以设置一些代理设置,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。
urllib中通过ProxyHandler来设置使用代理服务器,下面代码说明如何使用自定义opener来使用代理:
from urllib import request
# 这个是没有使用代码的
# resp = request.urlopen('http://httpbin.org/get')
# print(resp.read().decode("utf-8"))
# 这个是使用子代理的
handler = request.ProxyHander({"http":"218.66.161.88:31769"})
opener = request.build_opener(hander)
req = request.Request("http://httpbin.org/ip")
resp = opener.open(req)
print(resp.read())
常用的代理有:
* 西制免费代理IP:http://www.xicidaili.com/
* 快代理:http://www.kuaidaili.com/
* 代理云:http://www.dailiyun.com/
ProxyHandler处理器(代理):
1、代理的原理:在请求目的网站之前,先请求服务器,然后让代理服务器去请求目的网站,代理服务器拿到目的网站的数据后,再转发给我们的代码。
2、http://httpbin.org:这个网站可以方便的查看http请求的一些参数。
3、在代码中使用代理
-
使用”urllib.request.ProxyHandler“,传入一个代理,这个代理是一个字典,字典的key是"http" 或者 ”https“,依赖与代理服务器能够接收的类型,值是”ip:port“
-
使用上一步骤创建的“handler”,以及“request.build_opener”创建一个“opener”对象。
-
使用上一步创建的“opener”,调用“open”函数,发起请求。
实例代码如下:
from urllib url = 'http://httpbin.org/ip' # 使用代理的 # 1、使用ProxyHandler,传入代理 构建一个handler handler = request.ProxyHandler({"http":"14.20.235.107:9797"}) # 2、使用上面创建的handler构建一个opener opener = request.build_opener(handler) # 3、使用opener去发送一个请求 resp = opener.open(url) print(resp.read())
常用的代理:
-
西制免费代理IP:http://www.xicidaili.com/
-
快代理:http://www.kuaidaili.com/
-
代理云:http://www.dailiyun.com/
-
cookie
什么是cookie:
在网站中,http请求是无状态的。也就是说即使第一次和服务器链接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(coolie)给浏览器,然后浏览器保存砸本地,当该用户发送第二次请求的时候,就会自动的把上次请求储存的 coolie 数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。coolie储存的数据量有限,不同的浏览器有不同的储存大小,但一般不超过4kb。因此使用coolie只能储存一些小量的数据。
-
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协议下起作用。
-
使用cookielib库和HTTPCookieProcessor模拟登录:
Coolie 是指网站服务器为了辨别用户身份和进行Session跟踪,而储存在用户浏览器上的文本文件,cookie可以保持登录信息到用户下次与服务器的会话:
这里以人人网为例。人人网中,要访问某个人的主页,必须先登录才能访问,登录说白了就是要有cookie信息,那么如果我们想要用代码的方式访问,就必须要有正确的cookie信息才能访问。解决方案有两种,第一种是使用浏览器访问,然后将cookie信息复制下来,放到headers中。实例代码如下:
第一种:
#使用cookie可以实现模拟登陆的状态
From urllib import request
#大鹏董成主页:http://www.renren.com/880151247/profile
#人人网登陆:http://www.renren.com/PLogin.do
# cookie使用方式一
# 1、不使用cookie去请求大鹏的主页
depeng_url = "http://www.renren.com/880151247/profile"
headers = {
'User-Agent':"Mozilla/5.0 (Windows NT 10.0"
"; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
'Cookie':"anonymid=ki9qkk68-m4vjb6; depovince=ZGQT; _r01_=1; taihe_bi_sdk_uid=e9dd17147d9bd199dee38eae7f"
"956b79; wp_fold=0; taihe_bi_sdk_session=502aff0aec39a22ee93f38240f0719b9; JSESSIONID=abcI3qYv"
"RznIsehBK5Syx; t=a6a7a07491c536b0a776e4eac98be5249; societyguester=a6a7a07491c536b0a776e4eac9"
"8be5249; id=975486549; xnsid=d319569c; ver=7.0; loginfrom=null; jebecookies=f0f20ef5-f4a2-486d"
"-9d23-be5893e11d09|||||"
}
req = request.Request(url = depeng_url,headers = headers)
resp = request.urlopen(req)
# print(resp.read().decode('utf-8'))
# 将获取到的数据保存到本地
with open('renren.html','w',encoding='utf-8') as fp:
# write 函数必须写入一个str的数据类型
# resp.read()读出来的是一个bytes数据类型
# bytes -> decode(解码) -> str
# str -> encode(编码) -> bytes
fp.write(resp.read().decode('utf-8'))
第二种
# cookie使用方式二
from urllib import request
from urllib import parse
from http.cookiejar import CookieJar
from ProxyHandler import opener
# 大鹏董成主页:http://www.renren.com/880151247/profile
# 人人网登陆:http://www.renren.com/PLogin.do
headers = {
'User-Agent':"Mozilla/5.0 (Windows NT 10.0"
"; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
def get_opener():
# 1、登录
# 1.1 创建一个cookiejar对象
cookiejar = CookieJar()
# 1.2 使用cookiejar创建一个HTTPPCookieProoess对象
handler = request.HTTPCookieProcessor(cookiejar)
# 1.3 使用上一步创建的handler创建一个opener
handler = request.build_opener(handler)
return opener
def login_renren(opener):
# 1.4 使用opener发送登录的请求(人人网的邮箱和密码
data = {
'emali':"970138074@qq.com",
'password':"pythonspider"
}
login_url = "http://www.renren.com/PLogin.do"
req = request.Request(login_url,data = parse.urlencode(data).encode('utf-8'),headers = headers)
opener.open(req)
def visit_profile(opener):
# 2、访问个人主页
dapeng_url = "http://www.renren.com/880151247/profile"
# 获取个人主页的信息的时候,不要新家一个opener
# 而应该使用之前的那个opener,因为之前的那个opener已经包含了
# 登录所需要的cookie信息
req = request.Request(dapeng_url,headers=headers)
resp = opener.open(req)
with open('renren1.html',"w",encoding="utf-8") as fp:
fp.write(resp.read().decode("utf-8"))
if __name__ == '__main__':
opener = get_opener()
login_renren(opener)
visit_profile(opener)
-
保存cookie到本地
保存 cookie 到本地,可以使用 cookiejar 的 save 方法,并且需要指定一个文件名:
# 保存 cookie 到本地,可以使用 cookiejar 的 save 方法,并且需要指定一个文件名:
from urllib import request
from http.cookiejar import MozillaCookieJar
cookiejar = MozillaCookieJar('cookie.txt')
# cookiejar.load(ignore_discard=True) 把已经过期的cookie信息打印进来
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
# 向百度发送一个请求
resp = opener.open('http://www.baidu.com/')
# 打印返回值,得到的是cookie信息,也可以不用打印
# 保存百度的cookie信息
cookiejar.save()
#cookiejar.save(ignore_discard=True) # 保存即将过期的cooker信息