本文仅用于 Python 技术学习与交流分享,演示内容以公开可访问页面的结构化解析思路为主。示例运行前,请务必自行核验目标网站在发布当日的 `robots.txt`、页面提示、使用规则及相关法律要求;如页面出现访问限制、验证码、频控提示或规则不明确,应立即停止,不讨论任何绕过方式。本文不构成抓取建议,也不适用于商用、批量采集或二次分发场景。
最近做数据处理练习时,我尝试用 Python 搭了一套轻量的“公开页面信息整理 + 简单分析”流程。为了让过程尽量简单,这次只用 `requests`、`BeautifulSoup` 和 `pandas` 三个常见库,以公开榜单页为例,演示如何把网页里的基础信息整理成结构化数据。
一、开始前先说清楚:技术演示不等于可以随意抓取
做这类练习,前提不是“能不能抓下来”,而是“能不能合规地做”。这类技术分享里,我一般只坚持几个原则:
仅处理公开可访问页面中的基础信息,不碰账号信息、评论区、订单、搜索结果、用户画像等敏感内容。
在运行前核验目标站点当日规则;如 `robots.txt`、页面提示、服务规则存在不一致或含糊之处,以网站最新规则为准。
严格控制请求频率,设置访问间隔,不进行高频请求。
一旦页面返回异常、限制提示、验证码或访问拦截,立即停止,不尝试任何规避方式。
采集结果仅用于个人学习中的结构化处理练习,不做批量传播、商业使用或替代原站展示。
二、什么是 robots.txt?
robots.txt 是网站放在根目录下的一份访问规则说明,通常用来告诉爬虫哪些路径不建议访问(这一点做SEO的同学应该经常打交道,关于SEO、百度蜘蛛 以前也学过 后面单独给大家分享)常见位置就是:
https://example.com/robots.txt
User-agent: *Disallow: /search/Disallow: /cart/Allow: /books/bestsellers/Sitemap: https://example.com/sitemap.xml
可以这样理解:
User-agent: *:对所有爬虫生效
Disallow: /search/:不希望爬虫访问 /search/ 下的内容
Allow: /books/bestsellers/:允许访问某个具体路径
Sitemap:告诉爬虫网站地图地址,方便发现页面
不过也要注意,robots.txt 更像一种行业通用约定和访问礼仪,不等同于法律授权边界。即使某个路径没有写进 Disallow,也不代表就当然可以高频抓取、商用搬运或二次分发。实际使用时,仍然要结合网站页面提示、使用规则和具体场景综合判断;如遇限制提示、验证码或访问拦截,应立即停止。
三、技术选型
轻量场景下,不一定要上复杂框架。下面这几个库已经足够完成基础练习:
pip install requests beautifulsoup4 pandas
它们分别负责:
`requests`:发送 HTTP 请求
`beautifulsoup4`:解析 HTML
`pandas`:整理并保存结构化数据
四、核心示例:只提取少量基础字段
为了尽量降低风险,示例里只提取基础展示信息,例如书名、作者、价格和详情页链接,不抓取用户信息,不抓取评论,不做批量翻页,也不对异常页面反复重试。
import timeimport requestsimport pandas as pdfrom bs4 import BeautifulSoupBASE_URL = "http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent7-0-0-1-"HEADERS = { "User-Agent": "Mozilla/5.0"}MAX_PAGE = 3SLEEP_SECONDS = 5def fetch_and_parse(url, page_no): try: resp = requests.get(url, headers=HEADERS, timeout=10) time.sleep(SLEEP_SECONDS) if resp.status_code != 200: print(f"第 {page_no} 页请求失败,状态码:{resp.status_code}") return [] resp.encoding = resp.apparent_encoding soup = BeautifulSoup(resp.text, "html.parser") title_text = soup.title.get_text(strip=True) if soup.title else "" if "对不起" in title_text or "暂时没有找到" in soup.get_text(): print(f"第 {page_no} 页返回异常页面,已停止解析") return [] items = soup.find_all("li", class_="line") page_data = [] for item in items: try: name_div = item.find("div", class_="name") book_link = name_div.find("a") if name_div else None title = book_link.get("title", "").strip() if book_link else "" detail_url = book_link.get("href", "").strip() if book_link else "" publisher_info = item.find_all("div", class_="publisher_info") author = "未知" if publisher_info: author_links = publisher_info[0].find_all("a") if author_links: author = author_links[0].get_text(strip=True) price_tag = item.find("span", class_="price_n") price = price_tag.get_text(strip=True) if price_tag else "" if title: page_data.append({ "书名": title, "作者": author, "价格": price, "详情页": detail_url }) except Exception: continue return page_data except Exception as e: print(f"第 {page_no} 页请求异常:{e}") return []if __name__ == "__main__": results = [] print(f"开始采集,计划页数:{MAX_PAGE}") for page in range(1, MAX_PAGE + 1): print(f"正在处理第 {page} 页") url = BASE_URL + str(page) results.extend(fetch_and_parse(url, page)) if results: df = pd.DataFrame(results) df.to_csv("dangdang_bestsellers.csv", index=False, encoding="utf-8-sig") print(f"处理完成,共 {len(results)} 条,已保存为 dangdang_bestsellers.csv") else: print("本次未获取到有效数据")
这段代码的思路其实很简单:
这里我把输出改成了 `CSV`,这样不需要额外安装 Excel 相关依赖,复现会更直接一些。
五、如果要接入大模型,建议优先分析自有整理内容
很多朋友喜欢把网页信息抓下来后直接丢给大模型做总结,但更稳的方式其实是:只对自己整理后的简要文本做分析,而不是批量处理原网页长文本内容。
比如,我们可以基于“书名 + 手工整理的一句话摘要”做一个简单的文本分析:
import pandas as pddef build_prompt(book_name, note): return f"请用不超过3句话,总结《{book_name}》可能吸引读者关注的点:{note}"if __name__ == "__main__": df = pd.read_csv("dangdang_bestsellers.csv") for i in range(min(5, len(df))): book_name = df.loc[i, "书名"] note = "这里建议使用自己整理的简短描述,而不是直接批量使用网页长文本内容。" prompt = build_prompt(book_name, note) print(prompt)
这样做的好处是:
更容易控制输入长度
更适合做学习演示
也能减少对原始网页内容的大量复用
六、几个实践里常见的问题
中文乱码 可以使用 `resp.encoding = resp.apparent_encoding` 让程序自动识别页面编码。
页面结构变化 网页结构可能随时调整,代码跑不通时,先检查当前页面标签是否已变化。
请求失败或返回异常页 出现异常提示、限制页面或访问失败时,应停止继续请求,不做绕过尝试。
字段不稳定 不同榜单项的作者、出版社、价格标签可能并不完全一致,解析时要做好判空处理。
5. 分析输入过长
如果后续要接入大模型,建议先对文本做精简整理,再送入模型处理。
七、最后想说
这类练习真正有价值的地方,不是“抓了多少数据”,而是把一个公开页面里的信息,规范地整理成结构化结果,再衔接到自己的分析流程里。Python 的优势也就在这里:不需要很重的工具链,先把一个小问题跑通,就已经很有收获了。
不管你是想了解AI应用,还是有软件定制需求,都可以关注我的公众号,或者在评论区留言交流。
文末说明
本文仅作 Python 技术学习与交流分享,不构成抓取建议。示例仅展示公开页面基础信息的结构化处理思路,不讨论绕过限制,不适用于商用、批量采集或二次分发。使用前请结合目标网站最新规则及相关法律要求,自行判断合规性并承担相应责任。