Python + BS4实战:手把手带你爬取商业数据

Python + BS4实战:手把手带你爬取商业数据

目录

一、bs4篇

1.bs4介绍

1.1 什么是BeautifulSoup4?

1.2 为什么选择BeautifulSoup4?

      核心优势

2.bs4详解

2.1 首先下载bs4

2.2 接下来引入一个使用bs4的例子让我们快速熟悉它

2.3 运行结果

3.bs4使用实战案例

3.1 完整代码

3.2 为什么会影响翻页

3.3 反爬机制

3.4 已知信息

3.5 解决思路

3.6 结果展示

3.7 容易混淆的一点

3.8 图片爬虫


🌟 Hello,我是蒋星熠Jaxonic!
🌈 在浩瀚无垠的技术宇宙中,我是一名执着的星际旅人,用代码绘制探索的轨迹。
🚀 每一个算法都是我点燃的推进器,每一行代码都是我航行的星图。
🔭 每一次性能优化都是我的天文望远镜,每一次架构设计都是我的引力弹弓。
🎻 在数字世界的协奏曲中,我既是作曲家也是首席乐手。让我们携手,在二进制星河中谱写属于极客的壮丽诗篇!

在开始之前,大家可以先看我之前的两篇文章作为铺垫~

上一篇Re详解:正则表达式:用Python Re模块驯服文本数据的艺术-ZEEKLOG博客

上一篇Re的实战案例:Python爬虫抓取豆瓣TOP250数据-ZEEKLOG博客

一、bs4篇

经过上一个文章的学习我们发现Re模块配合正则表达式固然暴力直接,但是根据源代码一个个匹配写正则太过麻烦。

因此我们来引入一个新朋友:BeautifulSoup(bs4),并且附上实战案例~

让BS4告别繁琐的正则匹配~~~

1.bs4介绍

1.1 什么是BeautifulSoup4?

BeautifulSoup4(简称BS4)是Python中最流行的HTML/XML解析库,它能够从复杂的网页代码中优雅地提取出你需要的数据。无论是爬虫新手还是专业开发者,BS4都是网页数据提取的首选工具。

1.2 为什么选择BeautifulSoup4?

 核心优势

  • 语法简单:比正则表达式更直观易学
  • 容错性强:即使网页代码不规范也能正常解析
  • 支持多种解析器:兼容lxml、html.parser、html5lib等
  • Python风格:提供符合Python习惯的API设计

2.bs4详解

2.1 首先下载bs4

2.2 接下来引入一个使用bs4的例子让我们快速熟悉它

from bs4 import BeautifulSoup" <ul> <li><a href="zhangwuji.com">张无忌</a></li> <li><a href="zhouxingchi.com">周星驰</a></li> <li><a href="zhubajie.com">猪八戒</a></li> <li><a href="wuzetian.com">武则天</a></li> </ul> """ #1.初始化BeautifulSoup对象,处理的是html格式的,用html的解析器进行解析 page=BeautifulSoup(html,"html.parser") page.find("标签名",attrs={"属性":"值"}) #查找某个元素,只会找到一个结果 page.find_all("标签名",attrs={"属性":"值"}) #找到一堆结果 li=page.find("li",attrs={"id":"abc"}) a=li.find("a")#可以连续套娃find,这时对属性没有条件要求 print(a)#导出标签 print(a.text)#把标签里面的值导出来,拿文本 print(a.get("href"))#把标签里对应的href属性的值导出来,拿属性 li_list=page.find_all("li")#找到html代码中所有的带有li的标签,此时li_list接受的是列表 for li in li_list:#列表循环 a=li.find("a") text=a.text href=a.get("href") print(text,href) 

2.3 运行结果

可以发现都能得到我们想要的结果,相较于以前re那样原始的提取方式,bs4更显方便。

代码解析我都一步步放在了注释中,非常详细。

3.bs4使用实战案例

网址:北京新发地农副产品批发市场信息中心食品、农产品价格行情-食品商务网

可以发现数据从这里开始:

3.1 完整代码

import time from bs4 import BeautifulSoup import requests import random f=open("caijia.csv",mode="w",encoding="utf-8") # 写入CSV表头 f.write("产品名称,规格,平均价格,日期,趋势\n") numsum=0 #数据总数 n=1 #页数 while n<=29: url = f"https://price.21food.cn/guoshu-p{n}.html" #要进行伪装,否则提取的是网页主页源代码 headers={ "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36" } resp=requests.get(url,headers=headers) resp.encoding="utf-8" #print(resp.text) #1.初始化BeautifulSoup对象,处理的是html格式的,用html的解析器进行解析 page=BeautifulSoup(resp.text,"html.parser") uls=page.find_all("ul")#找到存有信息的范围标签(列表) #print(uls) #测试能否拿到ul数据 #进行循环遍历,找到对应的数据 num = 0 #每页的数据量 for ul in uls: tables = ul.find_all("table") for table in tables: tr = table.find("tr") tds=tr.find_all("td") if len(tds) >= 5: #防止提取的时候截断 name=tds[0].text.strip() size = tds[1].text.strip() price = tds[2].text.strip() date = tds[3].text.strip() if tds[4].text.strip() == "": # 检查是否为空字符串 trend = None else: trend = tds[4].text.strip() f.write(f"{name}{size}{price}{date}\n") num=num+1 #print(name,size,price,date,trend) print(f"第{n}页已经爬取完,共{num}条数据") numsum=num+numsum n=n+1 sleep_time = random.uniform(1, 2) time.sleep(sleep_time) f.close() resp.close() print(f"全部数据已经爬取完毕!!!共{numsum}条数据") 

这里翻页爬取时有个坑!博主在翻页爬的时候总是从第一页开始截断且报错:

经过反复研究代码,发现

3.2 为什么会影响翻页

没有条件检查时:

  • 程序遇到只有3个td的表格
  • 尝试访问 tds[4] 时出现 IndexError
  • 程序异常终止,无法继续执行到 n = n + 1
  • 所以卡在第一页

有条件检查时:

  • 程序遇到只有3个td的表格
  • 条件 len(tds) >= 5 为 False
  • 跳过这个表格,继续处理下一个
  • 所有表格处理完后,正常执行 n = n + 1
  • 继续下一页的爬取

3.3 反爬机制

由于网站限制,最终只能爬取五页数据,150条数据,研究了下发现网页有反爬验证。。。

3.4 已知信息

目前得到以下信息:

1.网站标记的是公网IP而不是代理IP

公网IP和代理池IP的区别:

形象比喻

  • 公网IP = 你的家庭住址
  • 代理池IP = 快递中转站/临时邮箱

详细区别对比

特征公网IP代理池IP
来源运营商分配给你的固定或动态IP代理服务商提供的第三方IP
归属你的真实网络身份中间服务器的IP
稳定性相对稳定频繁更换
成本免费(包含在网费中)需要付费购买
速度直接连接,速度快经过中转,速度较慢
匿名性低(直接暴露)高(隐藏真实IP)

2.一直爬取,公网IP会被禁,导致一直滑块验证(因为博主被禁了之后换成手机热点就好了)

3.在网页翻页多少次都不会触发滑块验证,除非把JS禁用了(说明网站会对JS环境做一个验证)

4.上述代码一个公网IP爬虫一次性只能爬5页

3.5 解决思路

这个我们后续再进行解决,目前的思路是:

思路1

避开滑块验证
1:设置动态公网IP(软路由)
2.模拟JavaScript执行和动态行为和丰富请求头(其它方法,例如Selenium)



浏览器执行的JS:


javascript

// 网站可能通过JS检测用户行为
document.addEventListener('mousemove', trackMouse)  // 鼠标移动
document.addEventListener('scroll', trackScroll)    // 滚动行为
document.addEventListener('click', trackClicks)     // 点击模式
setTimeout(trackBehavior, 5000)                     // 行为分析

代码爬虫:无JavaScript执行无事件监听无动态行为分析

思路2

利用JS解决滑块验证(但有个问题是如果一直爬取,公网IP会被禁导致一点数据都看不到了)

3.6 结果展示

3.7 容易混淆的一点

Re模块正则表达式提取:

这里的finditer是迭代提取(懒加载),并不是一次性都加载给result,而是一遍一遍迭代的过程中加载。

这里的find_all函数是一次性全加载给tables

特性区分:

特性正则表达式BeautifulSoup
数据提取方式.group("组名").text
返回对象类型正则匹配对象BeautifulSoup元素对象
语法item.group("name")item[0].text
适用场景简单文本提取复杂HTML结构解析

3.8 图片爬虫

关于图片的爬虫也类似:

1.利用拼接获得图片子页面的跳转路径

2.在子页面源代码中获得<img src>的标签拿到图片的下载路径

3.用requests请求图片的二进制内容

4.将二进制串转化成图片输出保存

样例代码:

# 下载图片 img_resp= requests.get(img_src) #print(img_resp.text)#注意,图片不是文本,不能获取text的内容 withopen(f"[n}.jpg",mode="wb")asf:#注意,此时写入到文件的是字节,所以必须是wbI f.write(img_resp.content)#把图片信息写入到文件中 

今天的分享就到这里啦~后面我会分享xpath的教程和本篇章的解决方案~谢谢大家!

■ 我是蒋星熠Jaxonic!如果这篇文章在你的技术成长路上留下了印记
■ 👁 【关注】与我一起探索技术的无限可能,见证每一次突破
■ 👍 【点赞】为优质技术内容点亮明灯,传递知识的力量
■ 🔖 【收藏】将精华内容珍藏,随时回顾技术要点
■ 💬 【评论】分享你的独特见解,让思维碰撞出智慧火花
■ 🗳 【投票】用你的选择为技术社区贡献一份力量
■ 技术路漫漫,让我们携手前行,在代码的世界里摘取属于程序员的那片星辰大海

Read more

Flutter 组件 oxy 适配鸿蒙 HarmonyOS 实战:响应式原子化状态管理,构建高性能局部刷新与副作用治理架构

Flutter 组件 oxy 适配鸿蒙 HarmonyOS 实战:响应式原子化状态管理,构建高性能局部刷新与副作用治理架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 oxy 适配鸿蒙 HarmonyOS 实战:响应式原子化状态管理,构建高性能局部刷新与副作用治理架构 前言 在鸿蒙(OpenHarmony)生态迈向极致流畅交互、涉及大量复杂实时仪表盘及超长列表渲染的背景下,如何实现状态的高效分发与局部更新,已成为决定应用“视口丝滑度”的核心架构命题。在鸿蒙设备这类强调 AOT 极致优化与 VSync 垂直同步波动的环境下,如果应用依然依赖全局的 setState 或过于沉重的树级状态注入(如传统的 Provider 模式),由于由于底层 OID 监听与 Widget 树重建带来的 CPU 抖动,极易由于由于“无效重绘”导致页面滚动时的微小掉帧。 我们需要一种能够实现原子化追踪、具备自动依赖收集且不依赖 Widget 树继承关系的极轻量响应方案。 oxy 为 Flutter

By Ne0inhk
开发兜不住?让数据库来兜底:金仓 SQL 防火墙的工程化实践

开发兜不住?让数据库来兜底:金仓 SQL 防火墙的工程化实践

开发兜不住?让数据库来兜底:金仓 SQL 防火墙的工程化实践 在真实的生产环境中,数据库安全从来不是“写完代码就结束”的问题,而是一个贯穿系统生命周期的持续对抗过程。哪怕你已经严格执行参数化查询、ORM 框架封装、输入校验等规范,仍然无法保证系统绝对无注入风险——遗留系统、动态 SQL、第三方组件、甚至临时脚本,都会成为潜在突破口。 这也是为什么越来越多企业开始将防线下沉到数据库层:既然应用层不可控,那就让数据库成为最后一道“强制执行的安全边界”。 本文结合 KingbaseES 的 SQL 防火墙机制,从原理、模式设计到性能表现,讲清楚它是如何在工程上解决 SQL 注入问题的。 一、SQL 注入的本质:语义劫持,而不是“字符串拼接问题” 很多人对 SQL 注入的理解还停留在“拼接字符串不安全”,但从数据库视角来看,本质其实是: 攻击者篡改了 SQL 的语义结构(

By Ne0inhk
Android 蓝牙 BLE 扫描 Native 层架构与扫描流程剖析

Android 蓝牙 BLE 扫描 Native 层架构与扫描流程剖析

博主简介 byte轻骑兵,现就职于国内知名科技企业,专注于嵌入式系统研发,深耕 Android、Linux、RTOS、通信协议、AIoT、物联网及 C/C++ 等领域。乐于技术分享与交流,欢迎关注互动! 📌 主页与联系方式ZEEKLOG:https://blog.ZEEKLOG.net/weixin_37800531知乎:https://www.zhihu.com/people/38-72-36-20-51微信公众号:嵌入式硬核研究所邮箱:[email protected](技术咨询或合作请备注需求) ⚠️ 版权声明 本文为原创内容,未经授权禁止转载。商业合作或内容授权请联系邮箱并备注来意。 本文基于 Android 蓝牙源码中 BLE 扫描相关的 Native 层代码,以scanInitializeNative为入口,系统梳理 BLE 扫描从 JNI

By Ne0inhk
【保姆级教程】手把手教你本地部署Open Claw,轻松实现智能爬虫![特殊字符]

【保姆级教程】手把手教你本地部署Open Claw,轻松实现智能爬虫![特殊字符]

🔥 前言 最近Open Claw在爬虫圈火得一塌糊涂!作为一款开源的高性能爬虫框架,它不仅支持分布式爬取,还内置了强大的反爬策略,简直是爬虫工程师的福音! 今天就带大家从零开始,在本地完整部署Open Claw,让你的爬虫效率直接起飞!💪 📝 准备工作 系统要求 * ✅ Windows 10/11 / macOS / Linux * ✅ Python 3.8+ * ✅ 8GB+ 内存(建议16GB) * ✅ 10GB+ 可用磁盘空间 需要安装的软件 1. Python环境(如果还没安装) 2. Git(用于克隆代码) 3. Docker(可选,推荐使用) 🚀 详细部署步骤 Step 1:安装Python依赖库 首先打开终端(Win+R输入cmd),执行以下命令: bash # 升级pip到最新版本 python -m pip

By Ne0inhk