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']}
- 有时候拿到一个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/
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
参数意义:
使用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':"[email protected]",
'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信息