python 基础 网络爬虫 day02

目录

1.解析

2.Fiddler常用菜单

3.请求方式及案例

4.requests模块


day01回顾

1.请求模块(urllib.request)

  1. Request(url,data=data,headers=headers)
  2. urlopen(请求对象)

2.响应对象res的方法

  1. res.read() ##数据类型:bytes
    res.read().decode('utf-8') ##数据类型:string
  2. res.getcode()
  3. res.geturl()

3.url编码模块(urllib.parse)

  1. urlencode(字典)
    原始数据:kw={'kw':'只手遮天'}
    urlencode后:kw=%e8%%e5%d3...  #字符串
  2. quote(字符串)
    s= '只手遮天'
    quote后:%e8%%e5%d3...
     
  3. unquote()

4.数据爬取步骤

  1. 找URL(拼接)
  2. 获取响应内容
  3. 保存

5.请求方式

  1. GET:查询参数在URL地址上显示
  2. POST(参数名data):查询参数在Form表单里
    注意:data一定腰围bytes数据类型
    data = {...}
    data = urlencode(data)
    data = bytes(data,'utf-8')  #字符串 - 字节流
    data.encode('utf-8')

day02

1.解析

  1. 数据的分类
    1. 结构化数据
      特点:有固定的格式,如:HTML,XML,JSON
    2. 非结构化数据
      示例:图片,音频,视频,这类数据一般都存储为二进制
  2. 正则表达式re
    1. 使用流程
      1. 创建编译对象:p = re.compile('正则表达式')
      2. 对字符串匹配:r = p.math('字符串')
      3. 获取匹配结果:print(r.group())
    2. 常用方法
      1. match(s):字符串开头的第一个返回对象
      2. search(s):从开始往后找,匹配第1个,返回对象
      3. group():从match或search返回对象中取值
      4. findall():所有全部匹配,返回一个列表
    3. 表达式
      .    匹配任意字符(不能匹配\n)
      \d  数字
      \s  空白字符
      \S 非空白字符
      [...] 包含[]内容:A[BCD]E -- ABE --ACE --ADE
      \w 字母,数字_

      * 0次或多次
      ?0次或1次
      + 1次或多次
      {m} m次
      {m,n} m-n次  AB{1,3}C -- ABC ABBC ABBBC

      贪婪匹配(.*) :在整个表达式匹配成功的前提下,尽可能多的匹配*

      非贪婪匹配(.*?):在整个表达式匹配成功的前提下,尽可能少的匹配*
       
    4. 示例(贪婪模式和非贪婪模式)示例
      import re
      
      s = """<div><p>仰天大笑出门去,我辈岂是蓬蒿人</div></p>
      <div><p>床前明月光,疑是地上霜</div></p>"""
      # 创建编译对象
      # re.S作用 :使 . 能够匹配 \n 在内的所有字符
      # 贪婪匹配 : .*  
      p = re.compile('<div><p>.*</div></p>',re.S)
      #非贪婪匹配 : .*?
      p = re.compile('<div><p>.*?</div></p>',re.S)
      # 匹配字符串s
      r = p.findall(s)
      print(r)
      
      
      #["<div><p>仰天大笑出门去,我辈岂是蓬蒿人</div></p>",
      # "<div><p>床前明月光,疑是地上霜</div></p>"]
      
    5. findall()的分组
      import re
      #解释 :先按照整体匹配出来,然后再匹配()中的
      # 如果有2个或者多个(),则以元组的方式取显示
      
      s = "A B C D"
      p1 = re.compile('\w+\s+\w+')
      print(p1.findall(s))
      # ['A B','C D']
      
      p2 = re.compile('(\w+)\s+\w+')
      # 第1步 :['A B','C D']
      # 第2步 :['A','C']
      print(p2.findall(s))
      
      p3 = re.compile('(\w+)\s+(\w+)')
      # 第1步 :['A B','C D']
      # 第2步 :[('A','B'),('C','D')]
      print(p3.findall(s))
      
    6. 练习 
      import re 
      
      s = """<div class="animal">
        <p class="name">
          <a title="Tiger"></a>
        </p>
        
        <p class="contents">
          Two tigers two tigers run fast
        </p>
      </div>
      
      <div class="animal">
        <p class="name">
          <a title="Rabbit"></a>
        </p>
        
        <p class="contents">
          Small white rabbit white and white 
        </p>
      </div>"""
      
      p = re.compile('<div class="animal".*?title="\
              (.*?)">.*?contents">(.*?)</p>',re.S)
      r = p.findall(s)
      #print(r)
      for animal in r:
          print("动物名称:",animal[0].strip())
          print("动物描述:",animal[1].strip())
    7. 案例1:内涵段子脑筋急转弯抓取
      网址:www.neihan8.com
      步骤:
      1. 找URL规律
        第一页 https://www.neihan8.com/njjzw/index.html
        第二页 https://www.neihan8.com/njjzw/index_2.html
        第三页 https://www.neihan8.com/njjzw/index_3.html
      2. 用正则匹配出 题目 和 答案
        p = re.compile('<div class="text-.*?title="(.*?)".*?<div class="desc">(.*?)</div>',re.S)
      3. 写代码
        1. 发请求
        2. 用正则匹配
        3. 写入本地文件
          import urllib.request
          import re
          
          class NeihanSpider:
              def __init__(self):
                  self.baseurl = "https://www.neihan8.com/njjzw/"
                  self.headers = {"User-Agent":"Mozilla/5.0"}
                  self.page = 1
                  
              # 下载页面
              def loadPage(self,url):
                  req = urllib.request.Request(url,headers=self.headers)
                  res = urllib.request.urlopen(req)
                  html = res.read().decode("utf-8")
                  self.parsePage(html)
                  
              # 解析页面
              def parsePage(self,html):
                  p = re.compile('<div class="text-.*?title="(.*?)".*?<div class="desc">(.*?)</div>',re.S)
                  r_list = p.findall(html)
                  # [("什么动物...","海豹"),(),()...]
                  self.writePage(r_list)
                  
              # 保存页面
              def writePage(self,r_list):
                  for r_tuple in r_list:
                      for r_str in r_tuple:
                          with open("急转弯.txt","a",encoding="gb18030") as f:
                              f.write(r_str.strip() + "\n")
                      with open("急转弯.txt","a",encoding="gb18030") as f:
                          f.write("\n")
                  
              def workOn(self):
                  self.loadPage(self.baseurl)
                  while True:
                      c = input("成功,是否继续(y/n):")
                      if c.strip().lower() == "y":
                          self.page += 1
                          url = self.baseurl + "index_" +\
                                str(self.page) + ".html"
                          self.loadPage(url)
                      else:
                          print("爬取结束,谢谢使用!")
                          break
                          
          if __name__ == "__main__":
              spider = NeihanSpider()
              spider.workOn()
    8. 猫眼电影top100榜单,存到csv表格文件中
      网址:猫眼电影 - 榜单 - top100榜
      目标:抓取电影名,主演,上映时间
      1. 知识点讲解
        1. csv模块的使用流程
          1. 打开csv文件
            with open('测试.csv','a') as f:
          2. 初始化写入对象
            writer = csv.writer(f)
          3. 写入数据
            writer.writerow(列表)
        2. 示例
          '''05_csv示例.py'''
          import csv
          
          with open("猫眼.csv","a",newline="") as f:
              # 初始化写入对象
              writer = csv.writer(f)
              #把列表写入到文件中
              writer.writerow(["电影名称","主演"])
              writer.writerow(["霸王别姬","张国荣"])
              writer.writerow(["唐伯虎点秋香","周星驰"])
      2. 准备工作
        1. 找URL
          第一页:http://maoyan.com/board/4?offset=0
          第二页:http://maoyan.com/board/4?offset=10
          第三页:http://maoyan.com/board/4?offset=20
          第n页:offset = (n-1)*10
        2. 正则匹配
          <div class="movie-item-info">.*?title="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>
      3. 写代码
        '''06_猫眼电影top100抓取.py'''
        import urllib.request
        import re
        import csv
        
        class MaoyanSpider:
            def __init__(self):
                self.baseurl = "http://maoyan.com/board/4?offset="
                self.headers = {"User-Agent":"Mozilla/5.0"}
                self.page = 1
                self.offset = 0
                
            # 下载页面
            def loadPage(self,url):
                req = urllib.request.Request(url,headers=self.headers)
                res = urllib.request.urlopen(req)
                html = res.read().decode("utf-8")
                self.parsePage(html)
                
            # 解析页面
            def parsePage(self,html):
                p = re.compile('<div class="movie-item-info">.*?title="(.*?)".*?<p class="star">(.*?)</p>.*?releasetime">(.*?)</p>',re.S)
                r_list = p.findall(html)
        #        print(r_list)
                # [("霸王别姬","张国荣","1994-01-01"),(),()...]
                self.writePage(r_list)
            
            def writePage(self,r_list):
                if self.page == 1:
                    with open("猫眼电影.csv","a",newline="",encoding='gb18030') as f:
                        writer = csv.writer(f)
                        writer.writerow(["电影名称","主演","上映时间"])
                for r_tuple in r_list:
                    with open("猫眼电影.csv","a",newline="",encoding='gb18030') as f:
                        # 创建写入对象
                        writer = csv.writer(f)
        #                L = list(r_tuple)
                        L = [r_tuple[0].strip(),r_tuple[1].strip(),r_tuple[2].strip()]
                        # ["霸王别姬","张国荣","1994-01-01"]
                        writer.writerow(L)
            
            def workOn(self):
                while True:
                    c = input("爬取请按y(y/n):")
                    if c.strip().lower() == "y":
                        self.offset = (self.page-1)*10
                        url = self.baseurl + str(self.offset)
                        self.loadPage(url)
                        self.page += 1
                    else:
                        print("爬取结束,谢谢使用!")
                        break
                        
        if __name__ == "__main__":
            spider = MaoyanSpider()
            spider.workOn()

2.Fiddler常用菜单

  1. Inspector:查看抓到的数据包的详细内容
    1. 分为请求(request)和响应(response)两部分
  2. 常用选项
    1. Haders:显示客户端发送到服务器的header,包含客户端信息,cookie,传输状态
    2. WebForms:显示请求的POST数据<body>
    3. Raw:将整个请求显示为纯文本

3.请求方式及案例

  1. GET
  2. POST
  3. Cookie 模拟登陆
    1. 什么是cookie,session
      HTTP是一种无连接协议,客户端和服务器交互仅仅限于 请求/响应过程,结束后断开,下一次请求时,服务器会认为是一个新的客户端,为了维护他们之间的链接,让服务器知道这是前一个用户发起的请求,必须在一个地方保存客户端信息
      cookie:通过在客户端记录的信息确定用户身份
      session:通过在服务端记录的信息确定用户身份
    2. 案例:使用cookie模拟登陆人人网
      步骤:
      1. 通过抓包工具,f12获取到cookie(先登陆1次网站)
      2. 正常发请求
        url:http://www.renren.com/967469305/profile
        '''07_cookie模拟登陆人人网.py'''
        import urllib.request
        
        url = "http://www.renren.com/967469305/profile"
        headers = {
                "Host":"www.renren.com",
                "Connection":"keep-alive",
                "Upgrade-Insecure-Requests":"1",
                "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
                "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
                "Referer":"http://www.renren.com/",
        #        Accept-Encoding: gzip, deflate
                "Accept-Language":"zh-CN,zh;q=0.9",
                "Cookie":"anonymid=jnoaljpk7d3nh2; depovince=BJ; _r01_=1; _de=4DBCFCC17D9E50C8C92BCDC45CC5C3B7; ln_uact=13603263409; ln_hurl=http://head.xiaonei.com/photos/0/0/men_main.gif; jebe_key=1b1f4a34-0468-4185-a3b0-6f2c38abc368%7C2012cb2155debcd0710a4bf5a73220e8%7C1540454149943%7C1%7C1540454153787; wp_fold=0; wp=0; jebecookies=2fc339e7-1b51-43ce-bc85-e2dc1f68ee16|||||; JSESSIONID=abcANrnqoMuLshY34pQAw; ick_login=30d0bd58-f6bb-437f-8d0d-6a72ae00e7b7; p=1e1b85cb8dda387a70e400a341c2e9c95; first_login_flag=1; t=4f652cc0a8f3fd50f5c9095c92d4717d5; societyguester=4f652cc0a8f3fd50f5c9095c92d4717d5; id=967469305; xnsid=55bff2d5; loginfrom=syshome"
            }
        
        req = urllib.request.Request(url,headers=headers)
        res = urllib.request.urlopen(req)
        print(res.read().decode("utf-8"))
        
         

4.requests模块

  1. 安装(用管理员身份去打开才Anaconda Prompt)
    Anaconda:conda install requests
    Window cmd : python -m pip install requests
    ##以管理员身份去执行pip安装命令
  2. 常用方法
    1. get(url,headers=headers):发起请求,获取响应对象
    2. response属性
      1. response.text:返回字符串类型
      2. response.content:返回bytes类型
        1. 应用场景:爬取非结构化数据
        2. 示例:图片保存
          import requests
          
          url = "http://dingyue.nosdn.127.net/LftiDijLShX6y8NWnEI606fo0TJmFMRIByj4HniV9GypR1539753512019.jpg"
          headers = {"User-Agent":"Mozilla/5.0"}
          
          res = requests.get(url,headers=headers)
          html = res.content
          
          with open("颖宝.jpg","wb") as f:
              f.write(html)
          
          print("图片下载成功")
      3. response.encoding
        网站一般返回:ISO-8859-1

        response.encoding = 'utf-8'
        手动返回utf-8
      4. response.status_code:返回服务器响应码
      5. response.url:返回数据URL地址
        '''08_requests模块示例.py'''
        import requests
        
        url = "http://www.baidu.com/"
        headers = {"User-Agent":"Mozilla/5.0"}
        # 发请求获响应
        response = requests.get(url,headers=headers)
        response.encoding = "utf-8"
        # 获取字符串
        print(type(response.text))
        # 获取字节流
        print(type(response.content))
        # 返回服务器响应码
        print(response.status_code)
        # 返回数据的URL
        print(respone.url)
        
        
        
        #print(respone.encoding)
        # 默认返回编码格式 :ISO-8859-1
    3. get()使用场景
      1. 没有查询参数
        res = requests.get(url,headers=headers)
      2. 有查询参数:params={}
        注:params参数必须为字典,自动进行编码
        示例见:
        '''09_requests.get.params.py'''
        import requests
        
        headers = {"User-Agent":"Mozilla/5.0"}
        url = "http://www.baidu.com/s?"
        key = input("请输入要搜索的内容:")
        params = {"wd":key}
        
        # 自动编码,自动拼接URL,params必须为字典
        res = requests.get(url,params=params,headers=headers)
        # 指定utf-8
        res.encoding = "utf-8"
        print(res.text)
        
    4. post()  参数名:data
      1. data = {}
      2. 示例 有道翻译
        '''10_有道翻译post.py'''
        import requests
        import json
        
        # 请输入你要翻译的内容
        key = input("请输入要翻译的内容:")
        # post方法要求data为字典格式
        data = {"i": key,
                "from":"AUTO",
                "to":"AUTO",
                "smartresult":"dict",
                "client":"fanyideskweb",
                "salt":"1540373170893",
                "sign":"a5d9b838efd03c9b383dc1dccb742038",
                "doctype":"json",
                "version":"2.1",
                "keyfrom":"fanyi.web",
                "action":"FY_BY_REALTIME",
                "typoResult":"false"
            }
        
        # 发请求,获取响应
        # url为POST的地址,抓包工具抓到的,此处去掉 _o
        url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
        headers = {"User-Agent":"Mozilla/5.0"}
        # 此处data为form表单数据
        res = requests.post(url,data=data,headers=headers)
        res.encoding = "utf-8"
        html = res.text
        # 把json格式字符串转换为Python中字典
        r_dict = json.loads(html)
        result = r_dict['translateResult'][0][0]["tgt"]
        print(result)
        
        # 作业 :把翻译后的结果输出来
        # 请输入要翻译的内容 :你好
        # hello
        
        #{'type': 'ZH_CN2EN', 
        # 'errorCode': 0, 
        # 'elapsedTime': 7, 
        # 'translateResult': 
        # [[{'src': '风云', 'tgt': 'Occasion'},{}],[]]
        #}

作业:

  1. 改写代码,用requests模块实现
  2. 链家二手房https://bj.lianjia.com/ershoufang/pg1/
  3. 百度搜索 链家 -> 二手房
  4. 爬取 :小区名称、总价

今日示例

猜你喜欢

转载自blog.csdn.net/qq_42584444/article/details/83374222