刘沙河 刘沙河
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希

花开半夏,半夏花开
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希
  • Python基础

  • Python进阶

  • Python并发编程

  • Django

  • Flask

  • 爬虫

    • 认识爬虫& request
    • bs4 和 xpath
      • 1.数据解析
      • 2.bs4 解析模块
        • 标签定位:
        • 提取数据
      • 3.xpath 解析
        • 标签定位
        • 提取数据
    • 代理-cookie-验证码识别-模拟登录
    • 线程池-协程-aiohttp-selenium
    • 移动端数据爬取-scrapy框架
    • scrapy框架-媒体文件爬取-middleware
    • 基于CrawlSpider全栈数据爬取,分布式爬虫
  • Python
  • 爬虫
bigox
2021-03-22
目录

bs4 和 xpath

# 1.数据解析

  • 解析: 根据指定的规则对数据进行提取

  • 作用: 实现聚焦爬虫

  • 数据解析方式:

    - 正则表达式
    - bs4
    - xpath
    
    1
    2
    3
  • 数据解析的通用原理:

    • 数据解析需要作用在页面源码中(一组html标签组成的)

      html:的核心作用是展示数据
      
      1
    • 通用原理:

      • 标签定位
      • 获取文本或者属性
  • 正则表达式实现数据解析

    # 需求:爬取糗事百科中糗图数据
    import requests
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
    }
    
    #方式1:
    url = 'https://pic.qiushibaike.com/system/pictures/12217/122176396/medium/OM37E794HBL3OFFF.jpg'
    img_data = requests.get(url=url,headers=headers).content #content返回的是byte类型的数据
    with open('./123.jpg','wb') as fp:
        fp.write(img_data)
        
    #方式2:
    from urllib import request
    url = 'https://pic.qiushibaike.com/system/pictures/12217/122176396/medium/OM37E794HBL3OFFF.jpg'
    request.urlretrieve(url,'./456.jpg')
    
    
    - 方式2不可以使用UA伪装的机制
    
    - urllib就是一个比较老的网络请求的模块,在requests模块没有出现之前,请求发送的操作使用的都是urllib
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

# 2.bs4 解析模块

  • 模块安装 :

    • pip install bs4
    • pip install lxml
  • bs4 的解析原理

    • 实例化一个beautifulSoup的对象,并且将即将被解析的源码数据加载到该对象中
    • 调用beautifulSoup对象中的相关属性和方法继续宁标签定位和数据提取
  • 如何实例化BeautifulSoup对象

    • BeautifulSoup(fp,'lxml'):专门用作于解析本地存储的html文档中的数据

      from bs4 import BeautifulSoup
      fp = open('./test.html','r',encoding='utf-8')
      soup = BeautifulSoup(fp,'lxml') #将即将被解析的页面源码加载到该对象中
      
      1
      2
      3
    • BeautifulSoup(page_text,'lxml'):专门用作于将互联网上请求到的页面源码数据进行解析

  • # 标签定位:

    • soup = BeautifulSoup(page_text,'lxml') 实例化一个对象

    • soup.tagName:定位到第一个TagName标签,返回的是单数

    • 属性定位:soup.find('tagName',attrName='value'),返回也是单数

      • find_all:和find用法一致,但是返回值是列表
    • 选择器定位:select('选择器'),返回值为列表

      • 标签选择器,类选择器,id选择器,层级选择器(>:一个层级,空格:多个层级)
      from bs4 import BeautifulSoup
      fp = open('./test.html','r',encoding='utf-8')
      soup = BeautifulSoup(fp,'lxml') #将即将被解析的页面源码加载到该对象中
      soup.p
      soup.find('div',class_='song')
      soup.find_all('div',class_='song')
      soup.select('.tang')
      soup.select('#feng')
      soup.select('.tang > ul > li')
      soup.select('.tang li')
      li_6 = soup.select('.tang > ul > li')[6]
      i_tag = li_6.i
      i_tag.string
      soup.find('div',class_='tang').text
      soup.find('a',id="feng")['href']
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
  • # 提取数据

    • 取文本:
      • tag.string:标签中直系的文本内容(只提取直系内的文本)
      • tag.text:标签中所有的文本内容
    • 取属性:
      • tag['attrName']
    # 爬取三国演义整篇小说内容http://www.shicimingju.com/book/sanguoyanyi.html
    
    url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
    page_text = requests.get(url,headers=headers).text
    soup = BeautifulSoup(page_text,'lxml')
    a_list = soup.select('.book-mulu > ul > li > a')
    fp = open('sanguo.txt','w',encoding='utf-8')
    for a in a_list:
        detail_url = 'http://www.shicimingju.com'+a['href']
        chap_title = a.string
        #对章节详情页的url发起请求,解析详情页中的章节内容
        detail_page_text = requests.get(detail_url,headers=headers).text
        soup = BeautifulSoup(detail_page_text,'lxml')
        chap_content = soup.find('div',class_="chapter_content").text
        fp.write(chap_title+':'+chap_content+'\n')
        print(chap_title,'爬取成功!')
    fp.close()
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

# 3.xpath 解析

  • 模块安装 :

  • pip install lxml

  • xpath的解析原理

    • 实例化一个etree类型的对象,且将页面源码数据加载到该对象中
    • 需要调用该对象的xpath方法结合着不同形式的xpath表达式进行标签定位和数据提取
  • etree对象的实例化

    • etree.parse(fileNane) 加载本地
    • etree.HTML(page_text) 加载网络请求的响应
  • xpath方法返回的永远是一个列表

  • # 标签定位

    • 在xpath表达式中最最侧的 / 表示的含义是说,当前定位的标签必须从根节点开始进行定位

    • xpath表达式中最左侧的 // 表示可以从任意位置进行标签定位

    • xpath表达式中非最左侧的 // 表示的是多个层级的意思

    • xpath表达式中非最左侧的 / 表示的是一个层级的意思

    • 属性定位://tagName[@arrtName='value']

    • 索引定位://tagName/li[3]

    • 定位条件可以多个,使用| 分开

      from lxml import etree
      tree = etree.parse('./test.html')
      tree.xpath('/html/head/meta')[0] #绝对路径
      tree.xpath('//meta')[0] #相对路径,将整个页面源码中所有的meta进行定位 
      #属性定位
      tree.xpath('//div[@class="song"]')
      #索引定位
      tree.xpath('//div[@class="tang"]/ul/li[3]') #该索引是从1开始
      
      #取文本
      tree.xpath('//p[1]/text()')
      
      #取属性
      tree.xpath('//a[@id="feng"]/@href')
      tree = etree.parse('./test.html')
      tree.xpath('/html/head/meta')[0] #绝对路径
      tree.xpath('//meta')[0] #相对路径,将整个页面源码中所有的meta进行定位
      
      #属性定位
      tree.xpath('//div[@class="song"]')
      #索引定位
      tree.xpath('//div[@class="tang"]/ul/li[3]') #该索引是从1开始
      
      #取文本
      tree.xpath('//p[1]/text()')
      tree.xpath('//div[@class="song"]//text()')
      
      #取属性
      tree.xpath('//a[@id="feng"]/@href')
      
      # 多个条件
      div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()')[0]
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
  • # 提取数据

    • 取文本:
      • /text():取直系的文本内容
      • //text():取所有的文本内容
    • 取属性直:
      • tag/@attrName
    # 需求:爬取boss的招聘信息
    from lxml import etree
    headers = {  # 反扒策略
        'User-Agent':',
        'cookie':''
    }
    url = 'https://www.zhipin.com/job_detail/?query=python%E7%88%AC%E8%99%AB&city=101010100&industry=&position='
    page_text = requests.get(url,headers=headers).text
    #数据解析	
    tree = etree.HTML(page_text)
    li_list = tree.xpath('//div[@class="job-list"]/ul/li')
    for li in li_list:
    #     需要将li表示的局部页面源码数据中的相关数据进行提取
    #     如果xpath表达式被作用在了循环中,表达式要以./或者.//开头
        detail_url = 'https://www.zhipin.com'+li.xpath('.//div[@class="info-primary"]/h3/a/@href')[0]
        job_title = li.xpath('.//div[@class="info-primary"]/h3/a/div/tex	t()')[0]
        salary = li.xpath('.//div[@class="info-primary"]/h3/a/span/text()')[0]
        company = li.xpath('.//div[@class="info-company"]/div/h3/a/text()')[0]
        #对详情页的url发请求解析出岗位职责
        detail_page_text = requests.get(detail_url,headers=headers).text
        tree = etree.HTML(detail_page_text)
        job_desc = tree.xpath('//div[@class="text"]//text()')
        job_desc = ''.join(job_desc)
        
        print(job_title,salary,company,job_desc)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    • 乱码处理

      • 对获取到的内容先编码再转码:

        img_name = img_name.encode('iso-8859-1').decode('gbk')
        
        1
#Python#
上次更新: 2023/04/16, 18:35:33
认识爬虫& request
代理-cookie-验证码识别-模拟登录

← 认识爬虫& request 代理-cookie-验证码识别-模拟登录→

最近更新
01
go与http代理
05-24
02
自制申威架构k8s-reloader
12-06
03
Docker Buildx 教程
12-01
更多文章>
Theme by Vdoing | Copyright © 2020-2024 小刘扎扎 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式