2019-05-10 | Python | UNLOCK

Python库之玩转urllib

哈哈,开心不,又到了写博客的时间,首先跟各位say sorry,这次博客内容的准备时间比较短,因为前两天健身房练的有点过了,有点没缓过来,顺便告诉关注我的小可爱们:如果你也在健身的话,请一定注意适当合理的去健身,因为健身过量的话很可能造成你的免疫力低下,反而对肌肉没有好处,好啦,言归正传,本周我们继续来说说Python的另一个库—urllib,ok,let’s begin!

我吹个牛逼啊,大家忍耐一下,虽然这部分内容的时间比较短,但是在上个学期我已经用Python写过一丢丢爬虫了,所以我觉得大家没必要担心这篇博客的质量会有所下降,大可不必,顺便说下,欢迎大家关注我的微信公众号(“哈haha”)



这部分我将会分成三个部分来说:

  • 第一部分 : urllib库的介绍
    • request模块
    • error模块
    • parse模块
    • robotparser模块
  • 第二部分 : requests库
  • 第三部分 : 上代码(爬取猫眼电影并进行数据可视化)

是不是想要快快开始了呢,好了,别让小姐姐等急了,开始~

综述

首先,我引入一个例子 : 假如一位小姐姐想要刷剧,比如说就是看夏至未至,那么她有两种方法 :

  • 在PC上通过浏览器进入腾讯视频官网进行查看
  • 安装腾讯视频客户端
  • (有的小姐姐肯定还想说,姑奶奶保存到云盘里,或者用爱奇艺等,别较真,我只是想说明以下这个例子)

ok,分析下,首先,目前为止从大的层面来讲,用户访问互联网资源有两种模式 : BS模式(browser-server)CS模式(client–server),对于BS架构这种来说,只需要客户机安装一个浏览器就可以访问天下所有的内容了(刚说的通过浏览器观看腾讯视频就是BS架构),而对于CS架构来说,客户机必须安装相应的客户端(也就是上面例子中的安装腾讯视频客户端),顺带提一句 : 我建议通过谷歌浏览器去观看腾讯视频或者干任何事,无论怎样,记住多多使用浏览器,为什么呢.原因很简单,就从最直观的一点来说,如果你安装客户端软件的话,是不是得定期更新,如果你通过浏览器去查看,你肯定看到的是最新的内容啊,这得省多少流量啊,省下流量的钱给女朋友买包包多好~🤭.
ok,扯远了,我想说的是 : 其实不管是BS还是CS架构,从大的范围来讲,这种方式都可以归结为10个字客户端请求服务端响应(我知道这句话漏洞很大,大佬先别喷,我只是引用一个例子),既然是通过客户端发起请求,服务端来响应这种方式的话,那我想知道,客户端是咋发请求的,发的是什么请求呢,HTTP、FTP还是其他的呢,这个请求我可以拦截下来么,我可以用Python来发一下吗,很好,能有这些问题很好,现在逐个来讲一下.

第一部分:urllib库的使用

  1. 抓取个人网站主页代码(request模块)
    import urllib.request
    response = urllib.request.urlopen("http://www.shipudong.com/")
    print(response.read().decode("utf-8"))
    


  • urlopen方法的几个参数:
    • data
      import urllib.parse
      import urllib.request
      #data参数是可选的,如果要添加参数,并且如果它是字节流编码格式的内容,即bytes类型,则需要bytes()方法转化
      data = bytes(urllib.parse.urlencode({"word":"hello"}),encoding="utf-8")
      response = urllib.request.urlopen("http://httpbin.org/post",data=data)
      print(response.read())
      
      【注】: 这里请求的站点是httpbin.org,它可以提供HTTP请求的测试
    • timeout
        import urllib.request
        response = urllib.request.urlopen("http://www.shipudong.com/",timeout=1)
        //程序超过1秒后,如果服务器没有请求,就会抛出URLError异常
        print(response.read())
      
  • 几个高级用法
    • HTTPDefaultErrorHandler : 用于处理HTTP响应错误,错误都会抛出HTTPError类型的异常
    • HTTPRedirectHandler : 用于处理重定向
    • HTTPCookieProcessor : 用于处理cookies
    • ProxyHandler : 用于设置代理,默认代理为空
    • HTTPPasswordMgr : 用于管理密码,它维护了用户名和密码的表
    • HTTPBasicAuthHandler : 用于管理认证,如果一个链接打开的时候需要认证,那么可以用它来解决验证问题

这里我说举两个例子说下:

  • HTTPBasicAuthHandler

      from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
      from urllib.error import URLError
    
      username = "username"
      password = "password"
      url = "http://localhost:5000/"
    
      p = HTTPPasswordMgrWithDefaultRealm()
      p.add_password(None,url,username,password)
      auth_handler = HTTPBasicAuthHandler(p)
      opener = build_opener(auth_handler)
    
      try:
          result = opener.open(url)
          html = result.read().decode("utf-8")
          print(html)
      except URLError as e:
          print(e.reason)
    

    【注】: 注意一点就是,上述代码是在本地开启一个服务端口,所以小姐姐们在自己本机上试验时,务必关掉防火墙和安全卫士这些东西,否则会一直报错滴~

  • 代理
    比伪装信息头更高端一点的方法就是使用IP代理池,因为对于一个网站来说,如果检测到某一个IP对于本网站的请求次数过多,就会对其实行IP封锁,说人话就是 : 不允许你访问我了,你太讨厌了.ok,那这不是思路就又来了么,你敢检测我IP,那我就访问几次换个新的IP接着访问,你咬我呀!

      from urllib.error import URLError
      from urllib.request import ProxyHandler,build_opener
    
      proxy_handler = ({
          //这里是你买的IP代理池
          //一般这样写:"http":"ip地址"或者"https":"ip地址"
      })
      opener = build_opener(proxy_handler)
      try:
          response = opener.open("http://www.shipudong.com/")
          print(response.read().decode("utf-8"))
      except URLError as e:
          print(e.reason)
    

    【注】: 推荐大家使用快代理

【注】: urlopen方法实现的是最简单的GET方法抓取

  1. 错误处理(error模块)
    不用多说了吧,上面的几个例子中都使用了错误处理.请参考上面.

  2. 解析链接(parse模块)
    urllib库里面提供了parse模块,它定义了处理URL的标准接口,例如实现URL各部分的抽取、合并以及链接转换.

ok,talk is cheap,show you my code😄

from urllib.parse import urlparse
result = urlparse("http://www.shipudong.com/2019/05/03/python-ku-zhi-selenium-de-shi-yong/")
print(type(result),result)

小姐姐请看控制台哟 :

<class 'urllib.parse.ParseResult'> ParseResult(scheme='http', netloc='www.shipudong.com', path='/2019/05/03/python-ku-zhi-selenium-de-shi-yong/', params='', query='', fragment='')

我就不解释了,我都能看懂,想必大家的智商就不用说了~多余的不多说,我直接说说API,大家自己试试,因为实在没意思 : <urlunparse()、urlsplit()、urlunsplit()、urljoin()、urlencode()、parse_qs()、parse_qsl()、quote()、unquote() >大家参考官网介绍学习

  1. 分析Robots协议(robotparser模块)
    Robots协议也叫爬虫协议、机器人协议,它的全名叫网络爬虫标准排除(Robots Exclusion Protocol),(看咱这英语水🤭)用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取.它通常是一个robots.txt的文本文件,一般放在网站的根目录下.
    说真话,我自己的网站没有这个协议,但是你们要想写的话,推荐这个网站,它会自动帮你生成.ok,这里以简书网站为例,说下其中字段代表的意思 :


第二部分:request库的使用

终于大概说完了urllib,说实话,我基本不用它,我用的是request,你是不知道,爽翻了啊!基本学习思路和urllib思路差不多,我就不赘述了~上段代码,让你体验下啥叫小清新

#你得确保你安装了requests这个库哟
import requests
url = "http://www.shipudong.com/"
result = requests.get(url)
print(type(result))
print(result.status_code)
print(result.text)
print(result.cookies)

ok,体验到了吧,不多说了,学习思路请参考urllib和官方文档

第三部分:上代码(爬取猫眼电影并进行数据可视化)

今天的文章写的有点长,很开心你能看到这,坚持到最后的人老天会给他奖励的,我就当个老天吧🤭,送你个例子 : 爬取猫眼电影并进行数据可视化
我们要分析的就是这个页面:




图中画红框部分的数据是变化的,所以必须每隔几秒就获取一次页面的数据,从而做到实时的刷新.
来,我们来打开浏览器控制台看看到底发生了什么:




说下思路 :
那是不是很简单,我只需要间隔一定时间(我的代码中间隔1秒)请求一次票房页面的新数据,然后取出相关字段的值,最后把新数据通过matplotlib库的相应的API将其渲染出来不就行了,ok,看代码~

import requests
import matplotlib as mpl
import matplotlib.pyplot as plt
import time
import pylab as pl
import sys
#一般网站最基本的反爬措施,伪装协议头headers
headers = {
   'accept':'*/*',
   'accept-encoding':'gzip, deflate, sdch, br',
   'accept-language':'zh-CN,zh;q=0.8',
   'origin':'https://piaofang.maoyan.com',
   'referer':'https://piaofang.maoyan.com/dashboard',
   'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64)
          AppleWebKit/537.36
          (KHTML, like Gecko) Chrome/58.0.3029.110 
          Safari/537.36 SE 2.X MetaSr 1.0'
}
#保证中文输出时不会乱码
mpl.rcParams["font.sans-serif"]=["SimHei"]
mpl.rcParams["axes.unicode_minus"]=False
#要爬取网站的url
url = "https://box.maoyan.com/promovie/api/box/second.json"
#用来存获取到的电影票房数据
arr = []
#记录横坐标的数据
a = []
#记录电影的名字
movie_name = []

#爬取电影网站票房信息
def acquireInfo():
   res = requests.get(url, headers=headers)
   res_con = res.json()
   for item in res_con["data"]["list"]:
       arr.append(item["boxInfo"])
       movie_name.append(item["movieName"])
   for i in range(1, 26):
       a.append(i)
   drawChart(movie_name)

#依据信息画图展示
def drawChart(str):
   plt.bar(a,arr,align="center",color="#7FFF00",tick_label=str)
   #使y轴坐标文字标签正常显示
 pl.xticks(rotation=-90)
   #设置图标的主题文字
 plt.title("猫眼电影实时票房信息")
   #设置x y 轴的名称
 plt.xlabel('电影名称')
   plt.ylabel('电影票房')
   plt.show()

#显示进度条
def view_bar(num, total):
   rate = num / total
   rate_num = int(rate * 100)
   r = ' \r %s>%d%%' % ('=' * num, rate_num,)
   sys.stdout.write(r)
   sys.stdout.flush()


if __name__ == '__main__':
   for i in range(0, 101):
       time.sleep(0.1)
       view_bar(i, 100)
   print("数据加载完成!")
   while 1:
       acquireInfo()
       #每0.1s请求一次网站,做到实时数据的刷新
    time.sleep(1)

到我的微信公众号查看效果的演示
【注】: 几种简单的反爬措施

  • 浏览器头的伪装




    当浏览器去访问一个网站的时候,它会携带一些相关信息,就是图中我用红框标记出来的,那很简单了,这不是思路就来了么,我也可以给我的爬虫加上这信息呀,是不是就可以初步伪装了呢

  • IP代理
    刚说过了,同一个IP如果多次访问一个网站,这个网站就会对其进行IP封锁.

  • 验证码登陆(图形验证码、极滑验证码、点触验证码、微博宫格验证码)
    这个应该算是比较高端的一种反爬措施了吧,由于小编之前写过公众号推文,推荐大家去看Python模拟网站登陆

OK,本周的分享就已经到这里就结束了,拜拜咯,小可爱们😗😗😗😗

评论加载中