Urllib库

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 函数进行详细的讲解:

  1. url :请求的url。

  2. date:请求的date,如果设置了这个值,那么将变成 post 请求。

  3. 返回值:返回值是一个 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':"[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信息

你可能感兴趣的:(python)