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

在爬虫技术中,解析和提取网页数据是核心部分。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 requestsresponse = 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 scrapyclass 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 requestsdef 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, authorsurl = 'http://example.com/articles'
titles, authors = fetch_data(url)print("Titles:", titles)
print("Authors:", authors)

使用 Scrapy 的例子

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

import scrapyclass 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 BeautifulSouplogging.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 codesoup = 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, authorsexcept 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.mzph.cn/diannao/50440.shtml

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

相关文章

基于微信小程序+SpringBoot+Vue的美食推荐平台(带1w+文档)

基于微信小程序SpringBootVue的美食推荐平台(带1w文档) 基于微信小程序SpringBootVue的流浪动物救助(带1w文档) 当微信小程序占领了多半江山&#xff0c;目前不分年龄和种族&#xff0c;使用频率最高&#xff0c;覆盖面积最广。使用人群使用的大多数都是微信小程序。目前国内最…

Kithara和Halcon (二)

Kithara使用Halcon QT 进行二维码实时识别 目录 Kithara使用Halcon QT 进行二维码实时识别Halcon 简介以及二维码检测的简要说明Halcon 简介Halcon的二维码检测功能 Qt应用框架简介项目说明关键代码抖动测试测试平台&#xff1a;测试结果&#xff1a; 开源源码 Halcon 简介以…

STM32CubeMX的介绍与简单使用

STM32CubeMX提供了一个直观的图形用户界面&#xff0c;允许用户通过简单的操作完成对STM32微控制器的配置&#xff0c;包括引脚分配、时钟配置、外设初始化等。专为STM32微控制器设计&#xff0c;旨在帮助开发者轻松配置和初始化STM32微控制器。用户可以通过拖拽和连接来配置芯…

关键词查找【Aho-Corasick 算法】

【全程干货】程序员必备算法&#xff01;AC自动机算法敏感词匹配算法&#xff01;动画演示讲解&#xff0c;看完轻松掌握&#xff0c;面试官都被你唬住&#xff01;&#xff01;_哔哩哔哩_bilibili 著名的多模匹配算法 引入依赖&#xff1a; <dependency><groupId>…

Vue3 Pinia/组件通信

2. pinaia 符合直觉的Vue.js状态管理库 集中式状态&#xff08;数据&#xff09;管理 官网 2.1 搭建pinaia环境 第一步&#xff1a;npm install pinia 第二步&#xff1a;操作src/main.ts import { createApp } from vue import App from ./App.vue/* 引入createPinia&…

37 Debian如何配置GlusterFS 10

作者:网络傅老师 特别提示:未经作者允许,不得转载任何内容。违者必究! Debian如何配置GlusterFS 10 《傅老师Debian知识库系列之37》——原创 ==前言== 傅老师Debian知识库特点: 1、拆解Debian实用技能; 2、所有操作在VMware虚拟机实测完成; 3、致力于最终形成Debian…

Java面试八股之什么是声明式事务管理,spring怎么实现声明式事务管理?

什么是声明式事务管理&#xff0c;spring怎么实现声明式事务管理&#xff1f; 声明式事务管理是一种编程范式&#xff0c;它允许开发人员通过声明性的配置或注解&#xff0c;而不是硬编码事务处理逻辑&#xff0c;来指定哪些方法或类应该在其上下文中执行事务。这种方法将事务…

13.CSS 打印样式表 悬停下划线动画

CSS 打印样式表 虽然我们不经常从网上实际打印内容,但打印样式表不应被忽视。它们可以用来确保你的网站内容以一种易读和适合打印的方式呈现。这里有一个简单的、独特的打印样式表,你可以用它作为自己的基础: media print {page {size: A4;}body {margin: 0;padding: 0;}body, …

【PHP】系统的登录和注册

一、为什么要学习系统的登录和注册 系统的登录和注册可能存在多种漏洞&#xff0c;这些漏洞可能被恶意攻击者利用&#xff0c;从而对用户的安全和隐私构成威胁。通过学习系统的登录和注册理解整个登录和注册的逻辑方便后续更好站在开发的角度思考问题发现漏洞。以下是一些常见…

Linux取消U盘自动挂载

Ubuntu 或其他GNOME桌面环境 打开“设置”&#xff1a; 点击桌面右上角的系统菜单&#xff0c;然后点击“设置”。 找到“可移动媒体”&#xff1a; 在设置窗口中&#xff0c;点击左侧的“可移动媒体”选项&#xff08;有些版本中&#xff0c;这个选项可能在“设备”或“文件”…

Husky 入门

Husky 是一个流行的 Node.js 工具&#xff0c;用于管理 Git 钩子。Git 钩子是在特定 Git 操作&#xff08;如提交、推送等&#xff09;发生时自动触发的脚本。Husky 允许你轻松地为你的项目添加这些钩子&#xff0c;以便在代码提交或推送之前自动执行检查、测试或其他任务。 安…

Eslint从安装到Vue项目配置

ESLint是一个静态代码分析工具&#xff0c;用于识别JavaScript代码中的模式&#xff0c;帮助开发者发现并修复代码中的问题。以下是从安装到在Vue 2项目中整合使用ESLint的详细步骤&#xff1a; 一、ESLint的安装 1. 全局安装&#xff08;可选&#xff09; 虽然全局安装ESLi…

JDK 21 中的虚拟线程与 Future

在 JDK 21 中&#xff0c;虚拟线程与 Future 的结合为异步编程提供了更强大和高效的解决方案。 Future 代表了异步计算的结果&#xff0c;通过它可以获取计算的状态和最终的结果。当与虚拟线程一起使用时&#xff0c;可以更灵活地管理和协调异步任务。 例如&#xff0c;在一个数…

C++第二十七弹---优先级队列的高级应用:结合仿函数优化性能

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1 priority_queue的介绍和使用 1.1 priority_queue的介绍 1.2 priority_queue的使用 2 仿函数的介绍和使用 2.1 仿函数的介绍 2.2 仿函数的…

Python升级打怪—Django入门

目录 一、Django简介 二、安装Django 三、创建Dajngo项目 (一) 创建项目 (二) 项目结构介绍 (三) 运行项目 (四) 结果 一、Django简介 Django是一个高级Python web框架&#xff0c;鼓励快速开发和干净、实用的设计。由经验丰富的开发人员构建&#xff0c;它解决了web开…

【文件fd】文件描述符fd | 文件描述表

目录 1.文件描述符fd 2.系统调用的0/1/2 3.C语言的stdin/stdout/stderr 4.系统调用的0/1/2和C语言的stdin/stout/stderr二者的关系❓ 5.文件描述表 5.1 文件描述符概念 5.3 文件对象strcut file 5.4 进程和文件对应关系 5.5 文件描述符理解 5.6 源码查看 1.文件描述…

谷粒商城实战笔记-55-商品服务-API-三级分类-修改-拖拽数据收集

文章目录 一&#xff0c;拖拽后结点的parentCid的更新二&#xff0c;拖拽后结点的父节点下所有结点的sort排序属性的变化更新排序的逻辑代码分析 三&#xff0c;拖拽后结点及其子节点catLevel的变化判断是否需要更新 catLevel获取拖动后的新节点 更新 catLevel完整代码 这一节的…

mysql特殊字符、生僻字存储设置

mysql utf-8模式下&#xff0c;分为ut8mb3,utf8mb4&#xff0c;mb4是支持特殊字符、emoji表情的&#xff0c;mb3是不支持的。 报错信息&#xff1a; 1### Error updating database. Cause: java.sql.SQLException: Incorrect string value: \xF0\xA8\x92\x82\xE6\x95... fo…

MongoDB教程(二十):MongoDB正则表达式

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、正则表…

【ESP32 idf 硬件I2C驱动MPU6050获取六轴数值】

目录 I2C介绍配置安装驱动通信创建&删除命令链接容器起始时序写数据读数据结束时序开始命令 mpu6050 硬件i2c驱动代码&调试代码调试 I2C 介绍 介绍部分可以看我写的【ESP32 idf 软件模拟I2C驱动MPU6050实现六轴加速度的获取】&#xff0c;这个是使用软件模拟的I2C时序…