当前位置: 首页 > news >正文

第3章 day03 xpath+反爬虫

上次直播作业

  • 下厨房的菜谱搜索(多个请求参数)

    • 通过抓包工具的分析发现,搜索菜谱的数据包有两个请求参数:

      • keyword:搜索的关键字
      • cat:1001固定形式
    • import requests#请求头
      headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
      }
      title = input('请输入菜名:')
      params = {'keyword':title,'cat':'1001'
      }
      #1.指定url
      url = 'https://www.xiachufang.com/search/'#2.发起请求
      response = requests.get(url=url,headers=headers,params=params)
      #处理乱码
      response.encoding = 'utf-8' #gbk#3.获取响应数据
      page_text = response.text#4.持久化存储
      fileName = title + '.html'
      with open(fileName,'w') as fp:fp.write(page_text)
  • 肯德基

    • http://www.kfc.com.cn/kfccda/index.aspx

      • 将餐厅的位置信息进行数据爬取

      • import requests
        head = { #存放需要伪装的头信息'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36'
        }
        #post请求的请求参数
        data = {"cname": "","pid": "","keyword": "天津","pageIndex": "1","pageSize": "10",
        }
        #在抓包工具中:Form Data存放的是post请求的请求参数,而Query String中存放的是get请求的请求参数
        url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
        #在post请求中,处理请求参数的是data这个参数不是params
        response = requests.post(url=url,headers=head,data=data)
        #将响应数据进行反序列化
        page_text = response.json()
        for dic in page_text['Table1']:name = dic['storeName']addr = dic['addressDetail']print(name,addr)
        

数据解析

何为数据解析

  • 概念:可以将爬取到的数据中指定的数据进行单独提取。

  • 作用:实现聚焦爬虫。

  • 数据解析通用原理:

    • 在一张页面中,想要解析的数据是存在于相关的html的标签中。
    • 可以先将指定的标签进行定位,然后可以将该标签中展示的数据进行提取。
  • 聚焦爬虫编码流程:

    • 指定url
    • 发起请求
    • 获取页面源码数据
    • 数据解析
    • 持久化存储
  • python中可以实现数据解析的技术:

    • 正则表达式(复杂度高)
    • bs4(python独有,学习成本较低)
    • xpath(通用性最强,最重要)
    • pyquery(css语句)

数据解析的主流策略

  • 具体解析的操作:

    • 在当前目录下新建一个test.html文件,然后将下述内容拷贝到该文件中

      • <html lang="en">
        <head><meta charset="UTF-8" /><title>测试bs4</title>
        </head>
        <body><div><p>百里守约</p></div><div class="song"><p>李清照</p><p>王安石</p><p>苏轼</p><p>柳宗元</p><a href="http://www.song.com/" title="赵匡胤" target="_self"><span>this is span</span>宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a><a href="" class="du">总为浮云能蔽日,长安不见使人愁</a><img src="http://www.baidu.com/meinv.jpg" alt="" /></div><div class="tang"><ul><li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li><li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li><li><a href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li><li><a href="http://www.sina.com" class="du">杜甫</a></li><li><a href="http://www.dudu.com" class="du">杜牧</a></li><li><b>杜小月</b></li><li><i>度蜜月</i></li><li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li></ul></div>
        </body>
        </html>
        

xpath(重点)

  • 环境安装:

    • pip install lxml
  • xpath解析的编码流程:

    • 创建一个etree类型的对象,把被解析的数据加载到该对象中
    • 调用etree对象中xpath函数结合不同形式的xpath表达式进行标签定位和数据的提取
  • xpath表达式如何理解?

  • from lxml import etree
    #1.创建一个etree的工具对象,然后把即将被解析的页面源码数据加载到该对象中
    tree = etree.parse('test.html')
    #2.调用etree对象的xpath函数然后结合着不用形式的xpath表达式进行标签定位和数据提取
    #xpath函数返回的是列表,列表中存储的是满足定位要求的所有标签
    #/html/head/title定位到html下面的head下面的title标签
    title_tag = tree.xpath('/html/head/title')
    #//title在页面源码中定位到所有的title标签
    title_tag = tree.xpath('//title')
    #属性定位#定位到所有的div标签
    div_tags = tree.xpath('//div')#定位到class属性值为song的div标签 //tagName[@attrName='value']
    div_tag = tree.xpath('//div[@class="song"]')
    #索引定位://tag[index]#注意:索引是从1开始的
    div_tag = tree.xpath('//div[1]')
    #层级定位# /表示一个层级  //表示多个层级
    a_list = tree.xpath('//div[@class="tang"]/ul/li/a')
    a_list = tree.xpath('//div[@class="tang"]//a')#数据提取#1.提取标签中的文本内容:/text()取直系文本  //text()取所有文本
    a_content = tree.xpath('//a[@id="feng"]/text()')[0]
    div_content = tree.xpath('//div[@class="song"]//text()')#2.提取标签的属性值://tag/@attrName
    img_src = tree.xpath('//img/@src')[0]
    print(img_src)
    

案例应用:碧血剑文本爬取

  • url:https://bixuejian.5000yan.com/

  • 需求:将每一个章节的标题和内容进行爬取然后存储到文件中

    #首页:章节名称,章节详情页的连接
    #详情页:章节内容import requestsfrom lxml import etree
    #存储小说文件的文件夹名称
    dir_name = 'xiaoshuoLib'headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36',
    }main_url = 'https://bixuejian.5000yan.com/'
    response = requests.get(url=main_url,headers=headers)
    response.encoding = 'utf-8'
    page_text = response.text#解析首页
    tree = etree.HTML(page_text)
    a_alist = tree.xpath('/html/body/div[2]/div/div[1]/div[3]/ul/li/a')for a in a_alist:#局部解析title = a.xpath('./text()')[0]detail_url = a.xpath('./@href')[0]detail_response = requests.get(url=detail_url,headers=headers)detail_response.encoding = 'utf-8'detail_page_text = detail_response.texttree = etree.HTML(detail_page_text)content_list = tree.xpath('/html/body/div[2]/div/div[1]/div[3]/div[4]//text()')content = ''.join(content_list)with open('./xiaoshuoLib/'+title+'.txt','w',encoding='utf-8') as fp:fp.write(title+'\n'+content)print(title,":章节内容爬取保存成功!")

简历模版下载:https://sc.chinaz.com/jianli/free.html

  • 下载当前页所有的建立模板

    • 简历名称+简历的下载链接

    • 根据简历的下载链接 下载简历文件

    • 根据下载地址下载的压缩包,压缩包是二进制的数据

      
      import requests
      from time import sleep
      from lxml import etree
      dir_name = 'jianliLib'headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36',
      }
      for page in range(1,3):if page == 1:main_url = 'https://sc.chinaz.com/jianli/free.html'else:main_url = 'https://sc.chinaz.com/jianli/free_%d.html'%pageresponse = requests.get(url=main_url,headers=headers)response.encoding = 'utf-8'page_text = response.texttree = etree.HTML(page_text)div_list = tree.xpath('//*[@id="container"]/div')for div in div_list:sleep(0.5)detail_url = div.xpath('./p/a/@href')[0]title =  div.xpath('./p/a/text()')[0]detail_page_text = requests.get(detail_url,headers=headers).texttree = etree.HTML(detail_page_text)#解析到了简历的下载链接down_load_url = tree.xpath('//*[@id="down"]/div[2]/ul/li[1]/a/@href')[0]data = requests.get(down_load_url,headers=headers).contentwith open('jianliLib/'+title+'.rar','wb') as fp:fp.write(data)print(title,'保存下载成功!')
  • 图片懒加载:

    • url:https://sc.chinaz.com/tupian/meinvtupian.html

      • 爬取上述链接中所有的图片数据
    • 主要是应用在展示图片的网页中的一种技术,该技术是指当网页刷新后,先加载局部的几张图片数据即可,随着用户滑动滚轮,当图片被显示在浏览器的可视化区域范围的话,在动态将其图片请求加载出来即可。(图片数据是动态加载出来)。

    • 如何实现图片懒加载/动态加载?

      • 使用img标签的伪属性(指的是自定义的一种属性)。在网页中,为了防止图片马上加载出来,则在img标签中可以使用一种伪属性来存储图片的链接,而不是使用真正的src属性值来存储图片链接。(图片链接一旦给了src属性,则图片会被立即加载出来)。只有当图片被滑动到浏览器可视化区域范围的时候,在通过js将img的伪属性修改为真正的src属性,则图片就会被加载出来。
    • 如何爬取图片懒加载的图片数据?

      • 只需要在解析图片的时候,定位伪属性的属性值即可
      import requests
      from time import sleep
      from lxml import etree
      dir_name = 'imgLib'headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36',
      }
      for page in range(1,3):if page == 1:url = 'https://sc.chinaz.com/tupian/meinvtupian.html'else:url = 'https://sc.chinaz.com/tupian/meinvtupian_%d.html'%pageresponse = requests.get(url=url,headers=headers)response.encoding = 'utf-8'page_text = response.texttree = etree.HTML(page_text)#解析图片地址div_list = tree.xpath('/html/body/div[3]/div[2]/div')for div in div_list:img_src = "https:"+div.xpath('./img/@data-original')[0]title = div.xpath('./div/a/text()')[0]+'.jpg'#对图片链接请求img_data = requests.get(img_src,headers=headers).contentwith open('imgLibs/'+title,'wb') as fp:fp.write(img_data)print(title,'保存下载成功!')
http://www.hskmm.com/?act=detail&tid=20959

相关文章:

  • 002- 学习环境搭建
  • 第10章 day10 DrissionPage详细教程
  • 求局部最小值
  • Element-UI的transfer穿梭框组件数据量大解决方案
  • 第9章 day09 hook插件
  • nginx 一致性hash和流量检查模块
  • 深入解析:10月底实习准备-Mysql(按面试频率准备)
  • 机器学习概述 - -一叶知秋
  • CEXE的%你赛5-题解
  • C++语言(1)
  • Windows多人共享文件夹全流程,附2025新共享文件快90%
  • 第11章 day11-day12关于json请求体/逆向爬虫实战
  • 容斥与二项式反演
  • react useCallback Hook详解
  • 从Docker构建失败到CRA被淘汰:一个React项目的ES模块探索记录
  • 充气泵PCBA方案中数字传感器和模拟传感器的差异
  • 实用指南:小米17手机的上市公司供应商
  • CDN + WAF + CLB + Higress 架构下的 TLS 加解密详细解析(适用阿里云)
  • react useMemo Hook详解
  • react useContext 详解
  • Python技能大赛-备赛建议
  • 【软件系统架构】系列七:系统性能——操作系统性能深入解析 - 实践
  • 你的下一款定位神器,何必是GPS?Nordic带你解锁Wi-Fi SSID的隐藏潜能
  • CF407E k-d-sequence 题目分析(0929模拟赛最后一题)
  • Linux 生成随机端口
  • MATLAB 中 dsp.FFT 系统对象:从原理到实践的完整指南
  • 并发编程可见性
  • C# Devexpress GridControl实现全选功能(转载,记录)
  • github Connection reset by 20.205.243.160 port 443 fatal: Could not read from remote repository.
  • VsCode Ai插件