python 基础 网络爬虫 day05

目录

1.json模块

2.动态网站数据抓取 - Ajax

3.selenium + phantomjs 强大的网络爬虫组合


day04

  1. lxml解析库
    1. 使用流程
      1. from lxml import etree
      2. parseHtml = etree.HTML(html)
      3. parseHtml.xpath('xpath表达式')
    2. xpath匹配规则
      1. 获取节点对象://div[@class="Tiger"]
      2. 获取节点属性值://div[@class="T"]//a/@src
      3. 函数://div[contains(@class,"a")]//a/@href
    3. xpath高级
      1. 基准xpath表达式(节点对象列表)
      2. for r in [节点对象列表]:
            username = parseHtml.xpath('./xpath表达式')
            ... ...

day05

1.json模块

  1. 什么是json?
    javascript中的对象和数组
    对象:{key:value}  取值:对象名.key
    数组:[...,...]           取值:数组[索引值]
  2. 作用
    json格式的字符串 和 python数据类型 之间的转换
  3. 常用方法
    1. json.loads():json格式  -->  Python数据类型
      json               python
      对象              字典
      数组              列表
      '''01_json.loads示例.py'''
      import json
      
      # json格式的数组
      jsarray = '[1,2,3,4]'
      # 数组 -> 列表
      L = json.loads(jsarray)
      print(type(L),L)
      
      # json格式对象
      jsobj = '{"city":"天地会","name":"步惊云"}'
      # 对象 -> 字典
      D = json.loads(jsobj)
      print(type(D),D)
    2. json.dumps():Python数据类型 --> json格式
      python           json
      字典               对象
      列表               数组
      元组               数组
      '''02_json.dunps示例.py'''
      import json
      
      L = [1,2,3,4]
      T = (1,2,3,4)
      D = {"city":"天地会","name":"聂风"}
      # python格式 -> json格式
      jsarray1 = json.dumps(L)
      print(type(jsarray1),jsarray1)
      
      jsarray2 = json.dumps(T)
      print(type(jsarray2),jsarray2)
      
      jsobj = json.dumps(D,ensure_ascii=False)
      print(type(jsobj),jsobj)


      ##注意:
      1. json.dumps()默认使用的是ascii编码
      2. 添加参数ensure_ascii=False,禁用ascii编码

2.动态网站数据抓取 - Ajax

  1. 特点:滚动鼠标滑轮时加载
  2. 案例:豆瓣电影排行榜数据抓取
    1. 抓取目标:豆瓣电影 - 排行榜 - 剧情
                        电影名称,评分
    2. 代码实现
      '''03_豆瓣电影抓取-Ajax.py'''
      import requests
      import json
      import csv
      num=input('请输入要爬取的数量:')
      url='https://movie.douban.com/j/chart/top_list'
      headers={
              'User-Agent':'Mozilla/5.0',
              }
      params={
              "type":"11",
              "interval_id":"100:90",
              "action":'',
              "start":"0",
              "limit":num,
              }
      res=requests.get(url,params=params,headers=headers)
      res.encoding='utf-8'
      # html为json格式的数组[{电影1信息},{},{}]
      html=res.text
      html=json.loads(html)
      #print(html)
      #用for循环遍历每一个电影信息
      
      with open('豆瓣电影.csv','a',newline='') as f:
          writer=csv.writer(f)
          for film in html:
              name=film['title']
              score=film['rating'][0]
              L=[name,score]
              writer.writerow(L)
      稍微高级点
      '''03_豆瓣电影抓取-Ajax.py'''
      import requests
      import json
      import csv
      
      # url要写抓到的GET :URL
      url = "https://movie.douban.com/j/chart/top_list?"
      headers = {"User-Agent":"Mozilla/5.0"}
      L = ["剧情","喜剧","动作"]
      tp_list = [{"剧情":"11"},{"喜剧":"24"},{"动作":"5"}]
      tp = input("请输入电影类型:")
      
      if tp in L:
          num = input("请输入要爬取的数量:")
          for film_dict in tp_list:
              for key,value in film_dict.items():
                  if tp == key:
                      params = {
                              "type":value,
                              "interval_id":"100:90",
                              "action":"",	
                              "start":"0",
                              "limit":num
                          }
                      
                      res = requests.get(url,params=params,headers=headers)
                      res.encoding = "utf-8"
                      # html为json格式的数组[{电影1信息},{},{}]
                      html = res.text
                      # 数组 -> 列表
                      html = json.loads(html)
                      # 用for循环遍历每一个电影信息{}
                      for film in html:
                          name = film['title']
                          score = film["rating"][0]
                          #{"rating":["9.6","50"],...}
                          with open("豆瓣电影.csv","a",newline="") as f:
                              writer = csv.writer(f)
                              L = [name,score]
                              writer.writerow(L)
      else:
          print("您输入的类型不存在!")

       

3.selenium + phantomjs 强大的网络爬虫组合

  1. selenium
    1. 定义:Web自动化测试工具,应用于Web自动化测试
    2. 特点
      1. 可以运行在浏览器,根据指定命令操作浏览器,让浏览器自动加载页面
      2. 只是工具,不支持浏览器功能,需要与第三方浏览器结合使用
  2. phantomjs
    1. 定义:无界面浏览器(无头浏览器)
    2. 特点
      1. 把网站加载到内存进行页面加载
      2. 运行高效
    3. 安装
      1. windows
        1. 将下载的可执行文件放到Python安装目录的Scripts目录下
          在cmd下搜索 where python
          然后找到python地址,放到Scripts目录
           
      2. Ubuntu
        1. 将下载的phantomjs放到一个路径下
        2. 添加环境变量
          vi .bashrc 添加
          export PHANTOM_JS=/home/.../phantomjs-2.1.1-...
          export PATH=$PHANTOM_JS/bin:$PATH
          终端:source .bashrc
          终端:phantomjs
  3. 示例代码
    1. 示例代码1:
      '''05_phantomjs+selenium示例1.py'''
      # 导入selenium库中的webdriver接口
      from selenium import webdriver
      
      # 创建phantomjs浏览器对象
      driver = webdriver.PhantomJS()
      # 发请求 get()
      driver.get("http://www.baidu.com/")
      print(driver.page_source)
      ## 获取网页截屏
      #driver.save_screenshot("百度.png")
      #print("图片保存成功")
      ## 关闭
      #driver.quit()
    2. 示例代码2:
      '''06_phantomjs+selenium示例2.py'''
      from selenium import webdriver
      import time
      
      # 创建浏览器对象
      driver = webdriver.PhantomJS()
      # 打开页面
      driver.get("http://www.baidu.com/")
      # 发送文字到搜索框
      kw = driver.find_element_by_id("kw")
      kw.send_keys("美女")
      # 点击 "百度一下"
      su = driver.find_element_by_id("su")
      su.click()
      time.sleep(1)
      # 获取截屏
      driver.save_screenshot("美女.png")
      # 关闭浏览器
      driver.quit()
  4. 常用方法
    1. driver.get(url)
      打开网站
    2. driver.page_source:获取响应的html源码
    3. driver.page_source.find('字符串')
      1. 作用:从html源码中搜索指定字符串
        -1:查找失败
        非-1:查找成功
    4. 单元素查找
      1. driver.find_element_by_id(" ").text
      2. driver.find_element_by_class_name(" ")
      3. driver.find_element_by_xpath('xpath表达式')
      4. 如果匹配到多个节点,则只返回第一个节点对象
    5. 多元素查找
      1. driver.find_elements_by_...
      2. 注意
        1. 如果结果1个,则返回节点对象,不是列表
        2. 如果结果n个,则返回列表
      3. 示例
        '''08_driver.find查找元素示例.py'''
        from selenium import webdriver
        
        driver = webdriver.Chrome()
        driver.get("https://www.qiushibaike.com/")
        
        # 查找单个节点 element
        r_One = driver.find_element_by_class_name("content")
        print(r_One.text)
        
        # 查找多个节点 elements
        r_Many = driver.find_elements_by_class_name("content")
        for r in r_Many:
            print(r.text)
            print()
        
        driver.quit()
    6. 对象名.send_keys("内容")
    7. 对象名.click()
  5. 案例1:登录豆瓣网站
    '''09_selenium+Chrome登陆豆瓣案例.py'''
    from selenium import webdriver
    import time
    
    # 创建浏览器对象,发请求
    driver = webdriver.Chrome()
    driver.get("https://www.douban.com/")
    time.sleep(0.5)
    # 获取截图(验证码)
    driver.save_screenshot("验证码.png")
    # 找 用户名、密码、验证、登陆豆瓣按钮
    uname = driver.find_element_by_name("form_email")
    uname.send_keys("19921510089")
    # 密码
    pwd = driver.find_element_by_name("form_password")
    pwd.send_keys("zhanshen001")
    # 验证码
    key = input("请输入验证码:")
    yzm = driver.find_element_by_id("captcha_field")
    yzm.send_keys(key)
    driver.save_screenshot("完成.png")
    # 点击登陆按钮
    login = driver.find_element_by_class_name("bn-submit")
    login.click()
    time.sleep(1)
    driver.save_screenshot("登陆成功.png")
    # 关闭浏览器
    driver.quit()
  6. 操作键盘
    1. 导模块
      from selenium.webdrier.common.keys import Keys
    2. 常用方法
      '''10_driver操作键盘示例.py'''
      from selenium import webdriver
      # 操作键盘
      from selenium.webdriver.common.keys import Keys
      import time
      
      # 创建浏览器对象,发请求
      driver = webdriver.Chrome()
      driver.get("http://www.baidu.com/")
      # 百度搜索框输入python
      kw = driver.find_element_by_id("kw")
      kw.send_keys("python")
      driver.save_screenshot("01_python.png")
      
      # 全选 :Ctrl + a
      kw = driver.find_element_by_id("kw")
      kw.send_keys(Keys.CONTROL,'a')
      driver.save_screenshot("02_CtrlA.png")
      
      # 剪切 :Ctrl + x
      kw = driver.find_element_by_id("kw")
      kw.send_keys(Keys.CONTROL,'x')
      driver.save_screenshot("03_CtrlX.png")
      
      # 粘贴 :Ctrl + v
      kw = driver.find_element_by_id("kw")
      kw.send_keys(Keys.CONTROL,'v')
      driver.save_screenshot("04_CtrlV.png")
      
      # 清空搜索框 : 对象名.clear()
      kw = driver.find_element_by_id("kw")
      kw.clear()
      driver.save_screenshot("05_Clear.png")
      
      # 输入 :达内科技
      kw = driver.find_element_by_id("kw")
      kw.send_keys("达内科技")
      driver.save_screenshot("06_Tarena.png")
      
      # 输入 :回车
      kw = driver.find_element_by_id("kw")
      kw.send_keys(Keys.ENTER)
      time.sleep(1)
      driver.save_screenshot("07_Enter.png")
      
      # 关闭浏览器
      driver.quit()
  7. 案例2:斗鱼直播网站主播信息抓取
    1. 抓取目标:主播名称,观众人数
      1. 主播:class --  dy-name ellipsis fl
        //div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"]
      2. 人数:class --  dy-num fr
        //div[@id="live-list-content"]//span[@class="dy-num fr"]
      3. 下一页按钮(能点的按钮):class -> shark-pager-next
      4. 下一页按钮(不能点的按钮):
    2. 代码实现
      '''11_斗鱼直播抓取案例.py'''
      from selenium import webdriver
      from lxml import etree
      import time
      
      # 把Chrome设置无界面浏览器
      opt = webdriver.ChromeOptions()
      opt.set_headless()
      # 创建浏览器对象,发请求
      driver = webdriver.Chrome(options=opt)
      driver.get("https://www.douyu.com/directory/all")
      i = 1
      
      # 循环
      while True:
          # 解析(driver.page_source)
          # 获取主播名称 和 观众人数
          parseHtml = etree.HTML(driver.page_source)
          names = parseHtml.xpath('//div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"]')
          numbers = parseHtml.xpath('//div[@id="live-list-content"]//span[@class="dy-num fr"]')
          
          for name,number in zip(names,numbers):
              print("\t主播名称:%s \t观众人数:%s" %
                    (name.text.strip(),number.text.strip()))
              #for name,number in [("主播1","20万"),("主播2","15万")]
          print("第%d页爬取成功" % i)
          i += 1
          # 判断是否需要点击下一页
          # 能点 :点击,继续循环
          if driver.page_source.find("shark-pager-disable-next") == -1:
              driver.find_element_by_class_name("shark-pager-next").click()
              time.sleep(1)
          else:
              break
          # 不能点 :break
      
      print("一共爬取了%d页" % i)
  8. Chromdriver如何设置无界面模式
        1、opt = webdriver.ChromeOptions()
        2、opt.set_headless()
        3、driver = webdriver.Chrome(options=opt)
        4、driver.get(url)
  9. 案例3:京东商品爬取
    1. 目标
      1. 商品名称
      2. 商品价格
      3. 评论数量
      4. 商家名称
    2. 代码实现
      '''12_京东商品爬取.py'''
      from selenium import webdriver
      import time
      import csv
      
      # 接受用户输入,访问京东
      pro = input("请输入要爬取的商品:")
      driver = webdriver.Chrome()
      driver.get("https://www.jd.com/")
      i = 1
      # 发送文字到搜索框,点击搜索
      text = driver.find_element_by_class_name("text")
      text.send_keys(pro)
      
      button = driver.find_element_by_class_name("button")
      button.click()
      time.sleep(1)
      
      while True:
          # 动态加载-->全部加载
          # 执行脚本,进度条拉到底部
          driver.execute_script(
             'window.scrollTo(0,\
              document.body.scrollHeight)')
          time.sleep(2) 
          # 正常解析爬取
          r_list = driver.find_elements_by_xpath\
                ('//div[@id="J_goodsList"]//li')
      
          # r为每一个商品的节点对象
          for r in r_list:
              m = r.text.split('\n')
              # ["¥52.80","Python...","200+",]
              if m[1] != "拍拍":          
                  price = m[0]
                  name = m[1]
                  commit = m[2]
                  market = m[3]
              else:
                  price = m[0]
                  name = m[2]
                  commit = m[3]
                  market = "拍拍"
              
              with open("商品.csv","a",newline="",encoding="gb18030") as f:
                  writer = csv.writer(f)
                  L = [name.strip(),price.strip(),
                       commit.strip(),market.strip()]
                  writer.writerow(L)
          
          print("第%d页爬取成功" % i)
          i += 1
          # 点击下一页
          if driver.page_source.find("pn-next disabled") == -1:
              driver.find_element_by_class_name("pn-next").click()
              time.sleep(1)
          else:
              print("抓取结束,共抓取%d页" % i)
              break
    3. 小提示:

      JS控制滚动条的位置:
      window.scrollTo(x,y);

      竖向滚动条置顶(window.scrollTo(0,0);
      竖向滚动条置底 window.scrollTo(0,document.body.scrollHeight)
      当前窗口driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
       

今日示例

猜你喜欢

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