03_基本庫(kù)的使用

urllib庫(kù)

  • python2中捶障,由urllib和urllib2兩個(gè)庫(kù)來(lái)發(fā)送請(qǐng)求泣懊,python3中沒(méi)有urllib2夫晌,統(tǒng)一為urllib
  • urllib的幾個(gè)模塊
    • request:最基本的http請(qǐng)求模塊麻献,
    • error: 異常處理的模塊
    • parse:工具模塊辨嗽,提供了許多url處理方法赌渣,比如拆分魏铅、解析、合并等
    • robotparser:識(shí)別網(wǎng)絡(luò)的robot.txt文件
  • request模塊下的幾個(gè)方法類
    • urlopen(url,data,timeoit)
      • url:必傳坚芜,請(qǐng)求資源的地址
      • data:可選览芳,必須是字節(jié)流格式,使用此方法后不再是get請(qǐng)求,而是post請(qǐng)求
      • timeout:設(shè)定超時(shí)時(shí)間
      from urllib import request, parse, error
      
      # urlopen(url, data)
      resp = request.urlopen("http://shuyantech.com/api/cndbpedia/avpair?q=%E6%B8%85%E5%8D%8E%E5%A4%A7%E5%AD%A6")  # 一個(gè)http響應(yīng)對(duì)象
      res = resp.read()  # 返回值為bytes編碼對(duì)象
      res = res.decode("utf-8")  # 對(duì)其解碼
      print(res)
      
      # data: 像url中動(dòng)態(tài)傳參數(shù),使用此方法后不再是get請(qǐng)求货岭,而是post請(qǐng)求
      params = {"q":"清華大學(xué)"}  # 定義參數(shù)
      # urlencode(dict)將參數(shù)字典轉(zhuǎn)化為字符串
      data = parse.urlencode(params)  # q=%E6%B8%85%E5%8D%8E%E5%A4%A7%E5%AD%A6
      # bytes(str,encode)將字符串轉(zhuǎn)化為字節(jié)流類型路操,并制定編碼格式
      data = bytes(data, encoding="utf8")  # b'q=%E6%B8%85%E5%8D%8E%E5%A4%A7%E5%AD%A6'
      resp = request.urlopen("http://shuyantech.com/api/cndbpedia/avpair?", data)
      res = resp.read() # b'{"status": "ok", "ret": [["\xe4\xb8\xad\xe6\x96\x87\xe5\x90\x8d", "\xe6\xb8\x85\xe5\x8d\x8e\xe5\xa4\xa7\xe5\xad\xa6"],
      res = res.decode("utf-8")  # {"status": "ok", "ret": [["中文名", "清華大學(xué)"],
      print(res)
      
      # timeout疾渴,設(shè)置超時(shí)時(shí)間,單位為秒
      try:
          resp = request.urlopen("http://shuyantech.com/api/cndbpedia/avpair?q=%E6%B8%85%E5%8D%8E%E5%A4%A7%E5%AD%A6", timeout=0.01)
          print(resp)  # urllib.error.URLError: <urlopen error timed out>
      except error.URLError as e:
          print(e.reason)  # timed out
          # isinstance,判斷對(duì)象是否為已知類型屯仗,與type的區(qū)別搞坝,isinstance() 會(huì)認(rèn)為子類是一種父類類型,考慮繼承關(guān)系魁袜,type則不考慮繼承關(guān)系
          import socket
          if isinstance(e.reason, socket.timeout):
              print("超時(shí)了")
      
    • Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False,method=None)
      • url:必傳桩撮,請(qǐng)求的資源地址
      • data:必須是bytes(字節(jié)流)類型的
      • headers:字典形式,構(gòu)造請(qǐng)求頭信息峰弹,例如User-Agent
      • method:字符串店量,指定請(qǐng)求方式
      • origin_req_host:請(qǐng)求方的host和ip
      • unverifiable:驗(yàn)證用戶有沒(méi)有權(quán)限接受請(qǐng)求結(jié)果
      from urllib import request, parse
      url = "http://httpbin.org/post"
      data = {
          "name":"Request"
      }
      headers = {
          "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36",
          "Host": "httpbin.org"
      }
      method = "POST"
      # 構(gòu)造請(qǐng)求信息
      req = request.Request(method=method, url=url, headers=headers, data=bytes(parse.urlencode(data), encoding="utf8") )
      resp = request.urlopen(req)
      res = resp.read().decode("utf-8")
      print(res)
      
    • Handler各種處理器和opener
      • HTTPBasicAuthHandler:用于管理認(rèn)證,當(dāng)一個(gè)連接打開(kāi)時(shí)鞠呈,需要登錄融师,可以用它來(lái)解決認(rèn)證問(wèn)題
      • HTTPCookieProcessor:用于處理cookie
      • HTTPPasswordMgr:用于管理密碼,維護(hù)了用戶名和密碼的表
      • HTTPRedirectHandler:用于重定向
      • ProxyHandler:用于設(shè)置代理蚁吝,默認(rèn)代理為空
      from urllib.request import ProxyHandler, build_opener
      from urllib.error import URLError
      
      url = "https://www.baidu.com"
      
      # 實(shí)例化代理
      p_handler = ProxyHandler({
          "http":"http://39.134.66.14:8080",
          "https":"https://218.38.52.132:80"
      })
      opener = build_opener(p_handler)  # build_opener(實(shí)例化的handler處理器)
      
      try:
          res = opener.open(url)
          html = res.read().decode("utf-8")
          print(html)
      except URLError as e:
          print(e.reason)
      
  • error:異常處理旱爆,定義了由request模塊產(chǎn)生的錯(cuò)誤
    • URLError:error模塊的基類,由request模塊產(chǎn)生的異常都可以通過(guò)這個(gè)類捕獲窘茁,存在reason屬性
    • HTTPError: URLError的子類怀伦,專門(mén)處理HTTP請(qǐng)求錯(cuò)誤 屬性code:返回的HTTP狀態(tài)碼,reason:錯(cuò)誤原因 headers:返回請(qǐng)求頭
    # 一個(gè)完整的異常捕獲例子
     from urllib import error,request
     try:
         resp = request.urlopen("http://cuiqingcai.com/index.html")
     except error.HTTPError as e:
         print("返回的狀態(tài)碼%s" % e.code)
         print("返回的錯(cuò)誤原因%s" % e.reason)
         print("返回的請(qǐng)求頭%s" % e.headers)
     except error.URLError as e:
         print("異常原因%s" % e.reason)
     else:
         print("成功")
    

-parse:解析鏈接山林,實(shí)現(xiàn)url各部分的抽取房待、合并、以及鏈接的轉(zhuǎn)換

  • urlparse:實(shí)現(xiàn)url的分段和識(shí)別驼抹,分成六段 scheme://netloc/path;params?query#fragment
    • scheme:表示協(xié)議
    • netloc:表示域名
    • path:表示訪問(wèn)路徑
    • params:代表參數(shù)桑孩,;后
    • query:代表查新條件,?后
    • fragment:表示錨點(diǎn)砂蔽,#后
    • urlparse(url, scheme,allow_fragments)
      • url:必填洼怔,待解析的url
      • scheme:默認(rèn)的協(xié)議,假如傳入的連接沒(méi)帶協(xié)議左驾,會(huì)采取這個(gè)默認(rèn)的協(xié)議
      • allow_fragments:是否忽略錨點(diǎn)部分镣隶,值為布爾類型
  • urlunparse:根據(jù)參數(shù),生成鏈接诡右,參數(shù)為可迭代對(duì)象安岂,且長(zhǎng)度為6
  • urlsplit: 與urlparse一樣,參數(shù)也形同解析url,分成五段帆吻,將params與path部分合并
    • urlsplit(url, scheme,allow_fragments)
  • urlunsplit: 參數(shù)為可迭代對(duì)象域那,且長(zhǎng)度為5
  • urljoin:生成鏈接,效果同urlunparse和urlunsplit,但此方法不需要長(zhǎng)度
    • urljoin(base_url,str) 將兩個(gè)參數(shù)合并對(duì)base_url的協(xié)議次员、域名败许、路徑進(jìn)行補(bǔ)充,base_url其他三個(gè)部分則不起作用
  • urlencode:將字典對(duì)象序列化成符合url參數(shù)格式的字符串,一般往url傳參中用
  • parse_qs:將url中的參數(shù)轉(zhuǎn)成字典
  • parse_qsl:將url中的參數(shù)轉(zhuǎn)化為元組組成的列表
  • quote:將數(shù)據(jù)轉(zhuǎn)化為url格式的編碼淑蔚,一般參數(shù)為中文的時(shí)候使用
  • unquote:將url格式的編碼進(jìn)行解碼
```
from urllib import parse
res = parse.urlparse("http:www.baidu.com/index.html;user?id=5#comment")
# 返回結(jié)果為元組市殷,res[0],res.scheme
print(res, res[0], res.scheme)  # ParseResult(scheme='http', netloc='', path='www.baidu.com/index.html', params='user', query='id=5', fragment='comment')

data = ["http", "www.baidu.com", "index.html", "user", "d=5", "comment"]
res = parse.urlunparse(data)
print(res)  # http://www.baidu.com/index.html;user?d=5#comment

res = parse.urlsplit("http:www.baidu.com/index.html;user?id=5#comment")
print(res)  # SplitResult(scheme='http', netloc='', path='www.baidu.com/index.html;user', query='id=5', fragment='comment')

data = ["http", "www.baidu.com", "index.html", "d=5", "comment"]
res = parse.urlunsplit(data)
print(res)  # http://www.baidu.com/index.html?d=5#comment

res = parse.urljoin("http://www.baidu.com", "index.html")
print(res)  # http://www.baidu.com/index.html ,注意合并的規(guī)則

data= {
    "name":"bob",
    "age":18
}
res = parse.urlencode(data, encoding="utf8")
print(res)  # name=bob&age=18

res = parse.parse_qs("http:www.baidu.com/index.html;user?id=5&name=3")
print(res)  # {'user?id': ['5'], 'name': ['3#comment']}

res = parse.parse_qsl("http:www.baidu.com/index.html;user?id=5&name=3")
print(res)  # [('user?id', '5'), ('name', '3')]

q= "張三"
res = "http:www.baidu.com/index.html?q=%s " % parse.quote(q)  # 編碼
print(res)  # http:www.baidu.com/index.html?q=%E5%BC%A0%E4%B8%89
res = parse.unquote(res)  # 解碼
print(res)  # http:www.baidu.com/index.html?q=張三
```
  • robotparse:分析網(wǎng)站的robot協(xié)議
    • robots.txt:網(wǎng)站爬蟲(chóng)協(xié)議,全稱網(wǎng)絡(luò)爬蟲(chóng)排除標(biāo)準(zhǔn)刹衫,一般存放于網(wǎng)站的根目錄下
    • 返回的內(nèi)容:
      • user-agent:設(shè)置可以爬取網(wǎng)站的爬蟲(chóng)名稱
      • disallow:設(shè)置哪些路徑不能爬取
      • allow:設(shè)置哪些路徑可以爬取
    # 京東的爬蟲(chóng)協(xié)議
    # url: https://www.jd.com/robots.txt
    User-agent: *   # 任何爬蟲(chóng)都可以爬
    Disallow: /?* 
    Disallow: /pop/*.html 
    Disallow: /pinpai/*.html?* 
    User-agent: EtaoSpider 
    Disallow: / 
    User-agent: HuihuiSpider 
    Disallow: / 
    User-agent: GwdangSpider 
    Disallow: / 
    User-agent: WochachaSpider 
    Disallow: /
    
    • RobotFileParser(url="") # 根據(jù)網(wǎng)站的robot協(xié)議來(lái)判斷爬蟲(chóng)是否有權(quán)限爬取
      • set_url():設(shè)置robots.txt文件的連接
      • read():讀取robots.txt文件并分析,無(wú)返回值醋寝,必須調(diào)用
      • parse():解析robots.txt文件
      • can_fetch(User-agent, url):返回值為布爾類型,判斷此user-agent是否可以爬取此url
      • mtime():返回值為上次抓取分析robots的時(shí)間
      • modified():將當(dāng)前時(shí)間設(shè)置為上次抓取的時(shí)間
    from urllib import robotparser
    
    rp = robotparser.RobotFileParser()  # 實(shí)例化分析類
    rp.set_url("https://www.jd.com/robots.txt")  # 添加robots地址
    rp.read()  # 讀取robot協(xié)議
    print(rp.can_fetch("*", "https://www.jd.com/")) # 判斷當(dāng)前爬蟲(chóng)是否可以爬取带迟, True
    print(rp.mtime())  # 上次抓取的時(shí)間 1553685029.0578604
    print(rp.modified())  # 設(shè)置抓取的時(shí)間 none
    

requests的使用

  1. 基本用法
    • Get請(qǐng)求 requests.get("url", "params", "headers")
      • url:請(qǐng)求資源的地址
      • params:傳入的參數(shù)
      • headers:請(qǐng)求頭音羞,反扒的一種措施
    • Post請(qǐng)求 requests.post("url", "params", "headers")
      • url:請(qǐng)求資源的地址
      • params:傳入的參數(shù)
      • headers:請(qǐng)求頭,反扒的一種措施
    • 響應(yīng)屬性信息
      • text:返回的文本數(shù)據(jù)
      • content:二進(jìn)制格式的數(shù)據(jù)仓犬,例如音頻嗅绰、視頻、圖片的
      • status_code:返回的狀態(tài)碼
      • headers:返回的響應(yīng)頭
      • cookies:cookies信息
      • url:請(qǐng)求的url信息
      • history: 請(qǐng)求歷史
     import requests
    
     # get請(qǐng)求 requests.get(url, params, headers)
     url = "http://httpbin.org/get"  # 請(qǐng)求的url
     # 請(qǐng)求參數(shù)
     params = {
         "name":"Arale",
         "age":25
     }
     # 請(qǐng)求頭
     headers = {
         "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36"
     }
     # 發(fā)送get請(qǐng)求婶肩,得到響應(yīng)
     resp = requests.get(url, params=params, headers=headers)
     print(resp.url)  # 打印請(qǐng)求的url 參數(shù)在url http://httpbin.org/get?name=Arale&age=25
     
     # post請(qǐng)求 requests.post(url, data, headers)
     url = "http://httpbin.org/post"  # 請(qǐng)求的url
     # 發(fā)送post請(qǐng)求
     resp = requests.post(url, data=params, headers=headers)
     print(resp.url)  # 打印請(qǐng)求的url 參數(shù)在請(qǐng)求體中 http://httpbin.org/post
     
     # 響應(yīng)屬性方法
     print(resp.text)  # 打印str文本數(shù)據(jù)
     print(resp.content)  # 處理二進(jìn)制數(shù)據(jù)办陷,例如圖片
     print(resp.url)  # http://httpbin.org/post
     print(resp.headers)  # {'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Thu, 28 Mar 2019 01:53:32 GMT', 'Server': 'nginx', 'Content-Length': '343', 'Connection': 'keep-alive'}
     print(resp.cookies)  # <RequestsCookieJar[]>
     print(resp.status_code)  # 200
     print(resp.history)  # []
    
  2. 高級(jí)用法
    • 上傳文件
     # 上傳文件
     files = {
         "file": open("01_urllib的使用.py", "rb")
     }
     resp = requests.post(url, files=files)  # 注意key必須為files否則報(bào)錯(cuò)
     print(resp.text)  # 返回內(nèi)容會(huì)多一個(gè)files字段
    
    • cookies的使用
      • 以簡(jiǎn)書(shū)為例,寫(xiě)文章的頁(yè)面需要登陸后才能看見(jiàn)律歼,拿到網(wǎng)站登錄后的cookie,再去請(qǐng)求,以達(dá)到維持登錄狀態(tài)的效果啡专。
     # cookie的使用
     headers = {
         # 此cookie為登錄網(wǎng)站后的cookie,
         "Cookie": "Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1553742403; sajssdk_2015_cross_new_user=1; locale=zh-CN; read_mode=day; default_font=font2; remember_user_token=W1sxMjE1NTM2Ml0sIiQyYSQxMSRmZEdzaHlpLnFsYnZpMG9PbFRQLk91IiwiMTU1Mzc0MjQxMC44MTg2OTc3Il0%3D--48708ad37562cd9a12cfaac066b92cc24e4305d3; _m7e_session_core=167a540dc0e51fd3bb10e0e502e174de; __yadk_uid=8uaAcl2jljk5KfYwGemwVKFoMN89sBuC; Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1553742450; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22169c243959d13-00d4259c8ce7dd-7a1b34-1296000-169c243959e606%22%2C%22%24device_id%22%3A%22169c243959d13-00d4259c8ce7dd-7a1b34-1296000-169c243959e606%22%2C%22props%22%3A%7B%7D%2C%22first_id%22%3A%22%22%7D",
         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36",
         "Referer": "http://www.reibang.com/writer"
     }
     url = "http://www.reibang.com/writer#/notebooks/35136025/notes/43035331"
     resp = requests.get(url, headers=headers)
     print(resp.status_code)  # 設(shè)置cookie,可以訪問(wèn)需要登錄才能看見(jiàn)的頁(yè)面200
     # 查看cookie,并可以得到cookie的key value
     cookie = requests.get("https://www.baidu.com/").cookies
     print(cookie)
     for k, v in cookie.items():
         print(k + "=" + v)
    
    • session會(huì)話維持
      • Session():用來(lái)維持同一個(gè)會(huì)話险毁,使用其實(shí)例化的對(duì)象進(jìn)行請(qǐng)求
       # session:維持會(huì)話
        session = requests.Session()  # 實(shí)例化session類,使請(qǐng)求為同一示例们童,即維持同一會(huì)話
        session.get("https://www.httpbin.org/cookies/set/arale/123456")
        resp = session.get("https://www.httpbin.org/cookies")
        print(resp.text)
      
    • ssl證書(shū)認(rèn)證
      • requests中有個(gè)參數(shù)verify,默認(rèn)weiTrue,會(huì)自動(dòng)驗(yàn)證網(wǎng)站的證書(shū)
      # ssl證書(shū)的驗(yàn)證畔况,verify參數(shù)默認(rèn)為T(mén)rue
        try:
            resp = requests.get("https://inv-veri.chinatax.gov.cn/")
            print(resp.status_code)  # requests.exceptions.SSLError會(huì)報(bào)錯(cuò),默認(rèn)會(huì)驗(yàn)證CA證書(shū)
        except Exception as e:
            # from requests.packages import urllib3
            # urllib3.disable_warnings()  # 忽略警告
            import logging
            logging.captureWarnings(True)  # 捕獲警告到日志的方式忽略警告
            resp = requests.get("https://inv-veri.chinatax.gov.cn/", verify=False)  # 不去驗(yàn)證證書(shū)
            print(resp.status_code)
      
    • 代理的設(shè)置
    # 代理ip的設(shè)置
     proxies = {
         "http":"http://47.107.227.104:8888",
     }
     resp = requests.get("https://www.baidu.com/", proxies=proxies)
     print(resp.status_code)
    
    • 超時(shí)設(shè)置
    # 設(shè)置超時(shí)
     try:
         resp = requests.get("https://www.baidu.com/", timeout=0.001)
         print(resp.status_code)  # requests.exceptions.ConnectTimeout
     except Exception as e:
         print(e)
    
    • 身份認(rèn)證
    # 傳入auth=(元組)
    resp = requests.get("url", auth=("user", "pwd")
    
    • prepared requests對(duì)象
      • 引入Request對(duì)象
        s = requests.Session()  # 實(shí)例化session對(duì)象
        req = requests.Request("get", "https://www.baidu.com/")  # 構(gòu)造請(qǐng)求對(duì)象 
        pre = s.prepare_request(req)  # 通過(guò)session準(zhǔn)備請(qǐng)求數(shù)據(jù)
        resp = s.send(pre)  # 發(fā)送請(qǐng)求數(shù)據(jù)慧库,返回響應(yīng)
        print(resp.status_code)
      

正則表達(dá)式

  • 常用方法
    • match(re, str):從開(kāi)頭開(kāi)始匹配跷跪,如果開(kāi)頭不符合,則匹配失敗
    • search(re,str):掃描整個(gè)字符串齐板,返回第一個(gè)符合條件的結(jié)果吵瞻,沒(méi)有匹配到,則返回none
    • findall(re,str):查找整個(gè)字符串甘磨,返回所有匹配到的結(jié)果
    • sub(re,要替換的內(nèi)容,str):替換匹配到的數(shù)據(jù)
    • compile(re):將匹配規(guī)則編譯成正則表達(dá)式對(duì)象橡羞,以達(dá)到復(fù)用的效果
  • 返回結(jié)果為sre_match對(duì)象,有兩個(gè)方法group()\span()
    • group():得到結(jié)果的內(nèi)容
    • span():得到匹配到的范圍济舆,即結(jié)果字符串在原字符竄中的位置范圍卿泽。
  • 分組:即字符串截取,用()包裹好想要提取的子字符串滋觉,調(diào)用group()方法签夭,并傳入分組索引即可得到齐邦,索引從1開(kāi)始
  • 通用匹配:., . 表示除換行符之外的任意字符,表示匹配前面字符0或多個(gè)
  • 貪婪與非貪婪:.* 表示貪婪模式第租,會(huì)盡可能的匹配多個(gè)導(dǎo)致匹配結(jié)果不準(zhǔn)確侄旬,.?表示非貪婪模式,盡可能匹配更少的煌妈,注意:非貪婪模式放在字符串結(jié)尾儡羔,可能會(huì)匹配不到*
  • 修飾符:第三個(gè)參數(shù),做修飾用
    • re.S:表示匹配包括換行符在內(nèi)的所有字符
    • re.I:表示對(duì)大小寫(xiě)不敏感
  • 轉(zhuǎn)移符: \璧诵,用來(lái)轉(zhuǎn)義特殊字符
import re

str = "Extra stings Hello 123456 world_This is a Regex Demo Exrea stings"

# + 表示一個(gè)或多了
# .*汰蜘?表示非貪婪模式
# \w{10}匹配字母數(shù)字下劃線10個(gè),{4,10}貪婪模式之宿,會(huì)取10個(gè)
# ()分組字符串提取
result = re.match(r"^extra.*?(\d+)\s(\w{10})", str, re.I)

print(result.group())  # 匹配結(jié)果的內(nèi)容
print(result.span())  # 結(jié)果字符串在原字符串中的位置范圍
print(result.group(1))  # 取出第一個(gè)分組結(jié)果
print(result.group(2))

爬取貓眼電影

  • 使用requests第三方庫(kù)族操,請(qǐng)求網(wǎng)站,用正則解析頁(yè)面,將解析結(jié)果寫(xiě)入excel
import requests
import re
import time
import xlwt


# 爬取網(wǎng)頁(yè)
def get_page(url, headers):
    resp = requests.get(url, headers)
    return resp.text


# 解析返回的結(jié)果
def parse_res(res):
    '''<dd>
        <i class="board-index board-index-1">1</i>
        <a href="/films/1203" title="霸王別姬" class="image-link" data-act="boarditem-click" data-val="{movieId:1203}">
          <img src="http://s0.meituan.net/bs/?f=myfe/mywww:/image/loading_2.e3d934bf.png" alt="" class="poster-default">
          <img data-src="https://p0.meituan.net/movie/223c3e186db3ab4ea3bb14508c709400427933.jpg@160w_220h_1e_1c" alt="亂世佳人" class="board-img" />
        </a>
        <div class="board-item-main">
          <div class="board-item-content">
            <div class="movie-item-info">
                <p class="name"><a href="/films/1203" title="霸王別姬" data-act="boarditem-click" data-val="{movieId:1203}">霸王別姬</a></p>
                <p class="star">
                    主演:張國(guó)榮,張豐毅,鞏俐
                </p>
                <p class="releasetime">上映時(shí)間:1993-01-01</p>
            </div>
            <div class="movie-item-number score-num">
                <p class="score">
                    <i class="integer">9.</i>
                    <i class="fraction">5</i>
                </p>
            </div>
          </div>
        </div>
       </dd>
    '''
    par = re.compile(r'<dd>.*?'
                     r'<i.*?>(\d+)</i>'
                     r'.*?data-src="(.*?)"'
                     r'.*?class="name"><a .*?>(.*?)</a>'
                     r'.*?class="star">(.*?)</p>'
                     r'.*?releasetime">(.*?)</p>'
                     r'.*?class="integer">(.*?)</i>'
                     r'.*?class="fraction">(.*?)</i>'
                     r'.*?</dd>', re.S)
    items = re.findall(par, res)  # 返回list
    for item in items:
        # 利用生成器返回?cái)?shù)據(jù),或者構(gòu)造元組比被,存放在list中用return返回
        # TODO 返回這樣格式是寫(xiě)入excel需要
        yield [
            item[0],
            item[1],
            item[2],
            item[3].strip()[3:],
            item[4][5:],
            item[5]+item[6]
        ]


# 寫(xiě)入文件
def write_to_excel(items):
    # 創(chuàng)建一個(gè)excel
    excel = xlwt.Workbook()
    # 添加一個(gè)工作區(qū)
    sheet = excel.add_sheet("電影排名")
    # 構(gòu)造表頭信息
    head = ["序號(hào)", "海報(bào)", "名稱", "主演", "上映時(shí)間", "評(píng)分"]
    # 將頭部信息寫(xiě)入excel表頭
    for index, value in enumerate(head):
        sheet.write(0, index, value)
    # 將內(nèi)容寫(xiě)入excel
    for row, item in enumerate(items, 1):  # 行數(shù)據(jù)
        for col in range(0, len(item)):  # 列數(shù)據(jù)
            sheet.write(row, col, item[col])

    excel.save("./貓眼電影排名.xlsx")


# 主程序入口
def main(offset):
    url = "https://maoyan.com/board/4?offset=" + str(offset)
    headers = {
        "User-Agent": '''Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
                        AppleWebKit/537.36(KHTML, like Gecko) Chrome
                        /73.0.3683.75 Safari/537.36'''
    }
    res = get_page(url, headers)  # 請(qǐng)求url
    items = parse_res(res)  # 解析結(jié)果色难,返回生成器
    print(items.__next__())  # python3改為_(kāi)_next__(),之前版本為next()
    return items  # 返回解析后的結(jié)果,生成器



if __name__ == "__main__":
    items = []
    offset = None
    for i in range(0, 10):
        item= main(i*10)  # 分頁(yè)爬取
        items += list(item)  # 將每頁(yè)結(jié)果進(jìn)行拼接
        time.sleep(1)  # 每頁(yè)休眠一秒鐘等缀,反扒措施
    write_to_excel(items)  # 將所有結(jié)果一次性寫(xiě)入文件枷莉,不一次一次寫(xiě),因?yàn)闀?huì)覆蓋
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尺迂,一起剝皮案震驚了整個(gè)濱河市笤妙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌噪裕,老刑警劉巖蹲盘,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異膳音,居然都是意外死亡召衔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)祭陷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)苍凛,“玉大人,你說(shuō)我怎么就攤上這事颗胡『辽睿” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵毒姨,是天一觀的道長(zhǎng)哑蔫。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么闸迷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任嵌纲,我火速辦了婚禮,結(jié)果婚禮上腥沽,老公的妹妹穿的比我還像新娘逮走。我一直安慰自己,他們只是感情好今阳,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布师溅。 她就那樣靜靜地躺著,像睡著了一般盾舌。 火紅的嫁衣襯著肌膚如雪墓臭。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,713評(píng)論 1 312
  • 那天妖谴,我揣著相機(jī)與錄音窿锉,去河邊找鬼。 笑死膝舅,一個(gè)胖子當(dāng)著我的面吹牛嗡载,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播仍稀,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼洼滚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了琳轿?” 一聲冷哼從身側(cè)響起判沟,我...
    開(kāi)封第一講書(shū)人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎崭篡,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吧秕,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琉闪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了砸彬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颠毙。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖砂碉,靈堂內(nèi)的尸體忽然破棺而出蛀蜜,到底是詐尸還是另有隱情,我是刑警寧澤增蹭,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布滴某,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏霎奢。R本人自食惡果不足惜户誓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望幕侠。 院中可真熱鬧帝美,春花似錦、人聲如沸晤硕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舞箍。三九已至舰褪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間创译,已是汗流浹背抵知。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留软族,地道東北人刷喜。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像立砸,于是被迫代替她去往敵國(guó)和親掖疮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • urllib and urllib2 區(qū)別 –博主提示:下面的是python2中的用法颗祝,python3需要做出相應(yīng)...
    sunnyRube閱讀 1,407評(píng)論 0 1
  • 一浊闪、需要導(dǎo)入的庫(kù)*** Settings ***Library CollectionsLibrary Stri...
    Gorden_x閱讀 4,332評(píng)論 0 3
  • 爬蟲(chóng)的基本流程 一、發(fā)送HTTP請(qǐng)求(Request)通過(guò)Python庫(kù)向目標(biāo)站點(diǎn)發(fā)送HTTP請(qǐng)求螺戳,等待服務(wù)器響應(yīng)...
    曉楓_0544閱讀 784評(píng)論 0 0
  • 前兩天有朋友問(wèn)我搁宾, 你還相信愛(ài)情嗎? 我說(shuō)相信啊倔幼, 他說(shuō)那你遇到過(guò)真愛(ài)嗎盖腿? 我說(shuō)我不知道, 他說(shuō)那你為什么還相信损同?...
    方辰閱讀 837評(píng)論 0 1
  • 日子開(kāi)心也是一天翩腐,不開(kāi)心也是一天! 今天的我是什么樣子的呢膏燃?充滿盼望充滿喜樂(lè)茂卦,在每個(gè)希望的土地和田野上!我們有的時(shí)...
    沐恩_d40f閱讀 316評(píng)論 0 1