Python爬虫技术 第13节 HTML和CSS选择器

news2024/11/16 22:37:55

在爬虫技术中,解析和提取网页数据是核心部分。HTML 和 CSS 选择器被广泛用于定位网页中的特定元素。下面将详细介绍这些选择器如何在 Python 中使用,特别是在使用像 Beautiful Soup 或 Scrapy 这样的库时。

在这里插入图片描述

HTML 选择器

HTML 选择器基于 HTML 元素的属性来定位和选择页面上的元素。以下是一些常见的 HTML 选择器类型:

  1. 标签选择器

    • soup.find_all('div') 将返回页面上所有的 <div> 标签。
  2. 类选择器

    • soup.find_all(class_='classname') 可以找到所有 class 属性为 classname 的元素。
  3. ID 选择器

    • soup.find(id='uniqueid') 可以找到 ID 为 uniqueid 的元素。
  4. 属性选择器

    • soup.find_all(attrs={'data-type': 'value'}) 可以找到具有指定属性和值的所有元素。
  5. 组合选择器

    • soup.select('div p') 使用 CSS 选择器语法来查找所有位于 <div> 内部的 <p> 标签。

CSS 选择器

CSS 选择器提供了更复杂的选择能力,它们可以基于元素的关系、位置和状态来选择元素。以下是 CSS 选择器的一些示例:

  1. 子选择器

    • #parent > .child 只选择直接作为 #parent 子元素的 child 类元素。
  2. 后代选择器

    • .container .item 选择所有在 .container 类内的 .item 类元素,无论嵌套多深。
  3. 相邻兄弟选择器

    • h1 + p 选择紧跟在 h1 元素后的 p 元素。
  4. 一般兄弟选择器

    • h1 ~ p 选择同级的 h1 元素之后的所有 p 元素。
  5. 伪类选择器

    • a:hover 选择鼠标悬停状态下的链接。

在 Python 中,Beautiful Soup 库使用 .select() 方法来解析 CSS 选择器,而 Scrapy 提供了 .css() 方法来实现类似功能。

示例代码

使用 Beautiful Soup:

from bs4 import BeautifulSoup
import requests

response = requests.get('http://example.com')
soup = BeautifulSoup(response.text, 'html.parser')

# 使用标签选择器
divs = soup.find_all('div')

# 使用类选择器
classname_elements = soup.find_all(class_='classname')

# 使用 CSS 选择器
container_items = soup.select('.container .item')

使用 Scrapy:

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['http://example.com']

    def parse(self, response):
        divs = response.css('div')
        classname_elements = response.css('.classname')
        container_items = response.css('.container .item')

以上就是使用 HTML 和 CSS 选择器在 Python 爬虫中抓取数据的基本方法。根据实际需求,你可以结合多种选择器来精确地定位和提取所需信息。

当然,让我们通过一些具体的例子来更深入地探讨如何在Python中使用Beautiful Soup和Scrapy结合HTML和CSS选择器来提取网页数据。

使用 Beautiful Soup 的例子

假设我们要从一个网站上抓取所有文章标题和作者信息,我们可以这样做:

from bs4 import BeautifulSoup
import requests

def fetch_data(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')

    # 假设标题在 <h2> 标签内,并且有 class "title"
    titles = [tag.text for tag in soup.find_all('h2', class_='title')]
    
    # 假设作者信息在 <span> 标签内,并且有 class "author"
    authors = [tag.text for tag in soup.find_all('span', class_='author')]
    
    return titles, authors

url = 'http://example.com/articles'
titles, authors = fetch_data(url)

print("Titles:", titles)
print("Authors:", authors)

使用 Scrapy 的例子

Scrapy 是一个更强大的框架,它允许异步请求和更复杂的爬虫逻辑。以下是一个简单的Scrapy爬虫的例子:

import scrapy

class ArticleSpider(scrapy.Spider):
    name = 'article_spider'
    start_urls = ['http://example.com/articles']

    def parse(self, response):
        # 使用 CSS 选择器来获取文章标题
        titles = response.css('h2.title::text').getall()
        
        # 获取作者信息
        authors = response.css('span.author::text').getall()
        
        # 遍历每一篇文章
        for title, author in zip(titles, authors):
            yield {
                'title': title,
                'author': author
            }

为了运行这个Scrapy爬虫,你需要在你的项目目录下创建一个与你的爬虫名称匹配的文件夹(例如 article_spider),并在其中创建一个 spiders 文件夹。然后在 spiders 文件夹里创建一个以你的爬虫名字命名的.py文件(例如 article_spider.py),并把上面的代码放进去。

处理分页和更复杂的数据结构

如果网站有分页,你可能需要在Scrapy中使用回调函数来处理每个页面。例如:

class ArticleSpider(scrapy.Spider):
    name = 'article_spider'
    start_urls = ['http://example.com/articles/page/1']

    def parse(self, response):
        # ... 提取文章标题和作者的代码 ...

        # 获取下一页的链接
        next_page = response.css('a.next-page::attr(href)').get()

        if next_page is not None:
            yield response.follow(next_page, self.parse)

在这个例子中,response.follow 方法会发送一个新的请求到 next_page URL,并调用 self.parse 函数处理响应。

以上就是使用Beautiful Soup和Scrapy结合HTML和CSS选择器进行数据抓取的基本示例。在实际应用中,你可能需要根据目标网站的具体HTML结构调整选择器。

在之前的代码基础上,我们可以进一步扩展功能,比如处理异常、增加日志记录以及优化数据存储。下面的示例将展示如何在 Beautiful Soup 和 Scrapy 中实现这些功能:

使用 Beautiful Soup 添加异常处理和日志记录

import logging
import requests
from bs4 import BeautifulSoup

logging.basicConfig(level=logging.INFO)

def fetch_data(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # Raises an HTTPError if the HTTP request returned an unsuccessful status code
        soup = BeautifulSoup(response.text, 'html.parser')
        
        titles = [tag.text for tag in soup.find_all('h2', class_='title')]
        authors = [tag.text for tag in soup.find_all('span', class_='author')]
        
        logging.info(f"Fetched {len(titles)} articles from {url}")
        return titles, authors
    except requests.exceptions.RequestException as e:
        logging.error(f"Error fetching data from {url}: {e}")
        return [], []

url = 'http://example.com/articles'
titles, authors = fetch_data(url)

if titles and authors:
    print("Titles:", titles)
    print("Authors:", authors)
else:
    logging.warning("No data fetched.")

在 Scrapy 中添加数据存储到 CSV 文件

在 Scrapy 中,你可以使用内置的 FeedExporter 来保存数据到不同的格式,如 JSON 或 CSV。以下是如何设置 Scrapy 项目以保存数据到 CSV 文件:

  1. 在你的 Scrapy 项目的 settings.py 文件中,添加以下配置:
FEEDS = {
    'articles.csv': {'format': 'csv'},
}

这将告诉 Scrapy 把输出保存到名为 articles.csv 的 CSV 文件中。

  1. 确保你的爬虫代码正确生成字典,并在 yield 中返回:
class ArticleSpider(scrapy.Spider):
    name = 'article_spider'
    start_urls = ['http://example.com/articles']

    def parse(self, response):
        titles = response.css('h2.title::text').getall()
        authors = response.css('span.author::text').getall()
        
        for title, author in zip(titles, authors):
            yield {
                'title': title,
                'author': author
            }
  1. 当你运行 Scrapy 爬虫时,它将自动将数据写入 articles.csv 文件。

处理更复杂的数据结构

如果数据结构非常复杂,可能需要多次解析或使用递归。例如,如果文章的详细信息在另一个页面上,你可以使用 Scrapy 的 follow 方法来访问和解析详情页面:

class ArticleSpider(scrapy.Spider):
    name = 'article_spider'
    start_urls = ['http://example.com/articles']

    def parse(self, response):
        article_links = response.css('a.article-link::attr(href)').getall()
        
        for link in article_links:
            yield response.follow(link, self.parse_article)

    def parse_article(self, response):
        title = response.css('h1.article-title::text').get()
        content = response.css('div.article-content *::text').getall()
        
        yield {
            'title': title,
            'content': content
        }

这样,你就可以更全面地处理和存储网络上的数据了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1948842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Llama 3.1和xAI超集群加速AI军备竞赛

LLama 3.1 先来看看LLama 3.1 405B的效果&#xff0c;例如输入生成上海印象的四连图&#xff0c;然后一键再生成短视频&#xff0c;整体还是可圈可点。 从下面的各项基准而言&#xff0c;LLama3.1系列在同等量级中均有不俗的表现&#xff0c;尤其是405B已经和闭源的GPT-4o不分…

内网横向:PTHPTKPTT

1.PHT横向 2.PTK横向 3.PTT横向 1.PHT横向&#xff1a; 条件&#xff1a;有管理员的NTLM Hash 并且目标机器开 放445端口 在工作组环境中&#xff1a; Windows Vista 之前的机器&#xff0c;可以使用本地管理员组内用户进行攻击。 WindowsVista 之后的机器&#xff0c;只能是…

【iOS】—— Block总结

Block总结 1. Block的使用规范2. __block修饰符__block修饰符的底层原理 3. Block的类型NSGlobalBlockNSStackBlockNSMallocBlock 4. Block的实现及本质初始化部分调用部分本质 5. Block的捕获与内存管理捕获变量捕获对象内存管理 6. 循环引用什么是循环引用循环引用解决方法1.…

抓包工具Charles

1、抓包的目的 遇到问题需要进行分析 发现bug需要定位 检查数据传输的安全性 接口测试时&#xff0c;开发给的需求文档不详细 在弱网环境下APP的测试 2、Charles是java语言编写的程序&#xff0c;本质是一个代理服务器&#xff0c;通过拦截服务端和客户端的http请求&#xff0…

谷粒商城实战笔记-63-商品服务-API-品牌管理-OSS获取服务端签名

文章目录 一&#xff0c;创建第三方服务模块thrid-party1&#xff0c;创建一个名为gulimall-third-party的模块2&#xff0c;nacos上创建third-party命名空间&#xff0c;用来管理这个服务的所有配置3&#xff0c;配置pom文件4&#xff0c;配置文件5&#xff0c;单元测试6&…

西瓜视频下载助手,支持批量下载视频!

我们每天都在接触海量的视频内容&#xff0c;但想要保存自己喜爱的视频却常常受限于平台的各种限制。因此&#xff0c;今天给大家带来一个超级实用的神器——西瓜视频下载助手。 西瓜视频下载助手&#xff08;电脑&#xff09; 工具支持西瓜视频的下载和今日头条的视频下载&a…

kafka详解及应用场景介绍

Kafka架构 Kafka架构&#xff0c;由多个组件组成&#xff0c;如下图所示&#xff1a; 主要会包含&#xff1a;Topic、生产者、消费者、消费组等组件。 服务代理&#xff08;Broker&#xff09; Broker是Kafka集群中的一个节点&#xff0c;每个节点都是一个独立的Kafka服务器…

如何使用EXCEL访问WinCC中的实时数据实现报表

如果项目已经做好了&#xff0c;不想改动现有项目。那么可以使用 EXCEL 通过 OPC 方式访问 WinCC 项目的数据。预先定义好 EXCEL 表格样式&#xff0c;通过以下方式实现。通过以下步骤打开 EXCEL 中的 VB 编辑器 引用 WinCC 提供的 OPC 客户端 Control 控件: Siemens OPC DAAut…

Godot游戏制作 04平台设计

新建创景&#xff0c;添加AnimatableBody2D节点。 添加Sprite2D节点 拖动图片 剪裁图片&#xff0c;吸附模式&#xff1a;像素吸附 添加CollisionShape2D&#xff0c;设置实际形状为矩形 重命名AnimatableBody2D节点为Platform&#xff0c;保存场景&#xff0c;拖动platform场景…

VirtualBox 安装Centos 7 避坑指南 SSH连不上 镜像失效 静态网络配置等

背景 几乎每次安装Centos 7 时&#xff0c;都会遇到各种各样的问题&#xff0c;毕竟每次安装动辄就是半年几年&#xff0c;几乎都是在换工作时&#xff0c;有了新机器才会倒腾一次&#xff0c;时间久远&#xff0c;就会忘记一些细节&#xff0c;这次整理一下&#xff0c;避免以…

数字图像处理笔记(三) ---- 傅里叶变换的基本原理

系列文章目录 数字图像处理笔记&#xff08;一&#xff09;---- 图像数字化与显示 数字图像处理笔记&#xff08;二&#xff09;---- 像素加图像统计特征 数字图像处理笔记&#xff08;三) ---- 傅里叶变换的基本原理 文章目录 系列文章目录前言一、傅里叶变换二、离散傅里叶变…

Vue3与Element-plus配合 直接修改表格中的一项数据——控制输入框的显示与隐藏

利用控制与隐藏输入框,直接修改表格中的每一项数据。 <!-- 表格模块 --> <div><el-table :data"tablelist" style"width: 100%"><el-table-column align"center" prop"deposit" label"接单押金">&l…

【动态规划】力扣.213. 打家劫舍 II

你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋&#xff0c;每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 &#xff0c;这意味着第一个房屋和最后一个房屋是紧挨着的。同时&#xff0c;相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一…

自动驾驶汽车普及之路

全球范围内自动驾驶汽车的普及正在加速。英国最近通过了 自动驾驶汽车法案 以便在未来几年内实现全自动驾驶和部分自动驾驶汽车安全融入社会。 更多自动驾驶汽车 目前&#xff0c;中国是世界上测试自动驾驶出租车最多的国家。而在美国&#xff0c;各大城市已将“自动驾驶出租车…

人工智能历史:从梦想到现实的变革之路

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

python机器学习8--自然语言处理(2)

1&#xff0e;移除用词 在很多情况下&#xff0c;有一些文章内的英文字符、标点符号分词的结果不符合自己的预期&#xff0c;会出现一些不想要的分词&#xff0c;此时就能通过以下的函数自己设定用词&#xff0c;并且删除。 jieba.analyse.set_stop_words("stop_words.tx…

哈默纳科HarmonicDrive谐波减速机的使用寿命计算

在机械传动系统中&#xff0c;减速机的应用无处不在&#xff0c;而HarmonicDrive哈默纳科谐波减速机以其独特的优势&#xff0c;如轻量、小型、传动效率高、减速范围广、精度高等特点&#xff0c;成为了众多领域的选择。然而&#xff0c;任何机械设备都有其使用寿命&#xff0c…

第五周:机器学习笔记

第五周学习周报 摘要Abstract机器学习——神经网络训练不起来怎么办&#xff1f;1. 局部最小点和鞍点1.1 Momentum(动量)1.2 Local minima和saddle point谁出现的情况更多&#xff1f; 2. 批次&#xff08;Batch&#xff09;2.1 Small Batch v.s. Large Batch Pytorch学习——T…

python项目通过docker部署到Linux系统并实现远程访问

背景需求&#xff1a;在Windows系统编写了简单的python代码&#xff0c;希望能通过docker打包到Linux Ubuntu系统中&#xff0c;并运行起来&#xff0c;并且希望在本地Windows系统中能通过postman访问。 目录 一、原本的python代码 二、创建一个简单的Flask应用程序 三、创…

SQL核心基础语法—快速入门MySQL

1.MySQL简介 MySQL其实是DBMS软件系统&#xff0c;也就是说MySQL并不是一个数据库&#xff0c;这是很多人的误区。我们经常听到的Oracle&#xff0c;MySQL&#xff0c;微软SQL Server&#xff0c;都是DBMS软件系统&#xff0c;我们只是通过这些系统来管理和维护数据库而已&…