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

【Python 量化入门】AKshare 保姆级使用教程:零成本获取股票 / 基金 / 期货全市场金融数据

【Python 量化入门】AKshare 保姆级使用教程:零成本获取股票 / 基金 / 期货全市场金融数据

做量化交易、财经数据分析、投资复盘的开发者和投资者,经常会遇到核心痛点:付费金融数据接口成本高、免费 API 注册流程繁琐、多市场数据分散难以整合。告别 QMT 回测烦恼!手把手教你搭建 MiniQMT+Backtrader 量化回测框架 本文就给大家详细讲解 Python 量化圈的开源神器AKshare,从安装到核心功能实战全覆盖,代码可直接复制运行,零基础也能一键获取全市场金融行情数据。 一、AKshare 是什么? AKshare 是一款基于 Python 开发的开源金融数据接口库,专为个人投资者、量化爱好者、财经数据分析人员打造,是目前国内生态最完善、维护最活跃的免费金融数据工具之一。 它支持股票、期货、基金、外汇、债券、指数、加密货币等多种主流金融市场的数据获取,核心优势如下: * 免费开源:完全开源免费,无隐藏收费,个人非商用零成本使用,无需开通付费会员 * 数据覆盖全面:A 股、

By Ne0inhk

双重机器学习之因果推断 | CATE条件平均处理效应估计:五大方法原理详解与模拟数据实战(python版)

家人们我又更新了,代码和科研绘图在论文末尾,欢迎大家评论点赞和收藏,你们的认可是我坚持的动力,祝大家科研顺利。 因果推断 | CATE条件平均处理效应估计:五大方法原理详解与模拟数据实战 本文是因果推断系列文章。本篇聚焦 CATE(Conditional Average Treatment Effect,条件平均处理效应) 的估计,从ATE的局限性讲起,深入介绍S-Learner、T-Learner、X-Learner、因果森林DML和线性DML五种主流方法的原理,并在模拟数据上进行完整的代码实操与效果对比。 1 从ATE到CATE:为什么需要异质性处理效应? 1.1 ATE只能回答"平均有没有用" ATE(Average Treatment Effect)回答的是:干预措施对整个群体的平均效果是什么? 但在实际业务中,我们更想知道的是:对于不同的个体或子群,干预效果有什么不同? 举几个例子: * 精准营销:给所有人发满减券ATE为正,但拆开看,高消费用户根本不需要券,低消费用户反而是增量用户——CATE帮你找到真正的增量人群。 * 个性化医疗:

By Ne0inhk
Python + AI:打造你的智能害虫识别助手

Python + AI:打造你的智能害虫识别助手

Python + AI:打造你的智能害虫识别助手 在农业生产中,病虫害是影响作物产量和品质的“隐形杀手”。传统的害虫识别依赖人工巡查,不仅耗时耗力,还容易因经验不足导致误判、漏判。而随着智慧农业的普及,AI技术正成为破解这一难题的关键——今天,我们就用Python从零搭建一个智能害虫识别助手,让电脑替你“火眼金睛”辨害虫,轻松搞定农作物病虫害预警! 一、为什么要做这个项目? 智慧农业的核心是“精准、高效、低成本”,而害虫识别正是其中的典型场景: * 对农户:无需专业植保知识,拍照就能识别害虫种类,快速匹配防治方案; * 对开发者:这是一个“小而美”的实战项目,覆盖AI开发全流程,从数据处理到模型部署,学完就能落地; * 技术价值:融合Python、深度学习、Web部署,是入门AI+垂直领域应用的绝佳案例。 这个项目不需要你有深厚的AI功底,只要掌握Python基础,跟着步骤走,就能做出一个能实际使用的智能识别工具。 二、项目核心技术栈 先明确我们要用到的工具,都是行业主流、

By Ne0inhk
C++中的父继子承:继承方式实现栈及同名隐藏和函数重载的本质区别, 派生类的4个默认成员函数

C++中的父继子承:继承方式实现栈及同名隐藏和函数重载的本质区别, 派生类的4个默认成员函数

🎬 胖咕噜的稞达鸭:个人主页 🔥 个人专栏: 《数据结构》《C++初阶高阶》《算法入门》 ⛺️技术的杠杆,撬动整个世界! 学习完本文,你将知道:(各位大佬预知答案几何请移步文章结尾!) 1. 当子类继承了父类,父类的私有成员在子类中是不可见的,所以父类的私有成员在子类中有没有被继承下来? 2. 子类对象一定比父类大? 3. 函数重载和函数隐藏的区别是什么?同名了有什么影响? 4. 派生类构造函数初始化列表的位置必须显式调用基类的构造函数,已完成基类部分成员的初始化? 5. 派生类构造函数先初始化子类成员,再初始化基类成员?派生类对象构造函数先调用子类构造函数,在调用基类构造函数? 接着来步入今天的正文: 面向对象三大特性:封装,继承,多态 我们之前学过了封装,类的定义是一个封装,迭代器实现也是一个封装,屏蔽了底层的实现细节。模板的使用也是一个封装。接下来讲解面向对象第二大特性:继承。 继承的定义: 假设大学学生和大学的老师,作为一个人的共性,都有姓名,住址和电话号码,但是不同的是,老师授课有职称,学生有学号,这是老师和学生不同的地方。

By Ne0inhk