尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Python爬虫入门实战:从Requests+BeautifulSoup到数据采集全流程

Python爬虫入门实战:从Requests+BeautifulSoup到数据采集全流程 1. 从“数据荒漠”到“信息绿洲”为什么我们需要爬虫几年前我接手一个市场分析项目需要了解某个细分领域所有竞品的公开定价和功能列表。当时我的第一反应是打开浏览器一家家官网去翻手动复制粘贴到Excel里。干了不到十家人就麻了——效率低下不说还容易出错数据格式也乱七八糟。那一刻我深刻体会到在数据驱动的时代没有自动化获取数据的能力就像在沙漠里用手捧水喝既慢又累还解不了渴。这就是Python爬虫的价值所在。它不是什么高深莫测的黑科技本质上就是一个自动化的数据采集程序模拟人类在浏览器上的操作访问网页、点击链接、翻页但速度是人类的成千上万倍并且不知疲倦、精准无误。无论是你想分析电商平台的商品价格趋势追踪社交媒体上的舆情热点还是批量下载公开的学术论文、图片素材爬虫都能将你从重复、繁琐的体力劳动中解放出来把宝贵的时间投入到更有价值的分析和决策上。很多人一听到“爬虫”就觉得是灰色地带其实不然。爬取公开的、非敏感的数据用于个人学习、研究或合法的商业分析在遵守网站robots.txt协议网站告知爬虫哪些页面可以抓取的君子协定和不过度占用服务器资源的前提下是普遍被接受的实践。它的核心是提升效率而不是突破边界。今天我们就来彻底拆解一下用Python爬取数据的完整流程、核心工具以及那些新手必踩的坑。我会假设你已经有最基础的Python语法知识知道变量、列表、循环我们从环境搭建开始一步步构建一个健壮可用的爬虫。2. 工欲善其事搭建你的爬虫作战环境写爬虫和写普通的Python脚本有点不一样它严重依赖几个第三方库。如果你还没配置好环境跟着下面的步骤来能避开90%的初期环境问题。2.1 Python安装与包管理工具pip首先确保你安装了Python。去Python官网下载最新稳定版比如3.8以上版本即可。安装时务必勾选“Add Python to PATH”这个选项这能让你在命令行CMD或终端里直接使用python和pip命令省去后续手动配置环境变量的麻烦。安装完成后打开命令行输入以下命令检查是否成功python --version pip --version如果都能正确显示版本号说明基础环境OK。pip是Python的包管理工具可以理解为Python世界的“应用商店”我们接下来需要的所有第三方库都通过它来安装。2.2 核心武器库Requests 与 BeautifulSoup对于绝大多数静态网页即打开网页后数据就直接在HTML源代码里的页面我们主要依赖两个库Requests 负责“敲门和取东西”。它模拟浏览器发送HTTP请求GET、POST等到目标网站并把服务器返回的网页内容HTML代码拿回来。它简单易用是网络请求的事实标准。BeautifulSoup (bs4) 负责“拆包裹和找宝贝”。服务器返回的HTML代码像一团乱麻BeautifulSoup能把它解析成一棵结构清晰的树然后让你能像使用CSS选择器一样轻松地找到并提取里面的特定数据如标题、价格、链接。安装它们只需一行命令pip install requests beautifulsoup4这里有个小细节包名是beautifulsoup4但在代码里导入时我们写from bs4 import BeautifulSoup。2.3 进阶与伪装应对复杂场景随着你爬取的网站越来越复杂可能会遇到以下情况动态加载 数据不是一开始就在HTML里而是网页加载后由JavaScript代码通过Ajax请求后台API获取并渲染的。这时候用Requests拿到的HTML是空的看不到数据。反爬机制 网站为了防止被过度抓取会检测请求头、验证IP频率、甚至要求登录。为此你需要更多工具Selenium / Playwright 它们可以控制一个真实的浏览器如Chrome去访问网页能完整执行页面里的JavaScript等数据加载完成后再获取HTML。相当于派了一个“机器人”去帮你操作浏览器适合解决动态加载问题但速度较慢资源消耗大。请求头Headers伪装 用Requests时默认的请求头很简陋网站一眼就能认出是爬虫。我们需要把请求头伪装成普通浏览器的样子最关键的是User-Agent字段。headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 } response requests.get(url, headersheaders)代理IP池 如果单个IP在短时间内发送过多请求容易被封。使用代理IP可以轮换不同的IP地址降低风险。但免费代理大多不稳定商用代理需要成本初学者可以先从控制请求频率加延时做起。对于本文我们将聚焦在最常用、最经典的Requests BeautifulSoup组合上掌握它们你就已经能解决70%以上的爬虫需求了。3. 庖丁解牛拆解一个完整的爬虫工作流理论说再多不如动手做一遍。我们以一个简单的实战为例爬取一个豆瓣电影Top250列表页面https://movie.douban.com/top250上的电影名称和评分。请注意实际操作前请查看该网站的robots.txt并确保你的爬取行为温和、有间隔仅用于学习。3.1 第一步观察与分析——开发者工具是你的眼睛在写代码之前一定要先手动打开目标网页按F12打开浏览器的“开发者工具”。这是爬虫工程师最重要的“眼睛”。切换到“Elements”元素标签页这里可以看到网页完整的HTML结构。使用左上角的箭头工具或按CtrlShiftC去点击页面上你想抓取的数据比如一个电影名。开发者工具会自动定位到该数据对应的HTML代码位置。仔细观察它的标签结构和属性。比如你可能会发现每个电影条目都包裹在一个div classitem里电影名在一个span classtitle标签内评分在一个span classrating_num标签内。切换到“Network”网络标签页然后刷新页面。这里记录了浏览器发出的所有请求。如果数据是动态加载的你可能会看到一些XHR或Fetch类型的请求这些就是Ajax请求直接抓取这些请求的地址往往更高效。但我们这个例子是静态页面。通过观察我们确定了数据的位置和特征接下来就可以用代码来模拟了。3.2 第二步获取数据——Requests发起请求现在我们用Requests去获取这个页面的HTML内容。import requests from bs4 import BeautifulSoup url https://movie.douban.com/top250 # 伪装成浏览器的请求头 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 } try: response requests.get(url, headersheaders) # 检查请求是否成功状态码200表示成功 response.raise_for_status() # 设置正确的编码防止中文乱码 response.encoding response.apparent_encoding html_content response.text print(页面获取成功) except requests.RequestException as e: print(f请求出错{e}) html_content None if html_content: # 接下来就可以用BeautifulSoup解析了注意这里使用了try...except来捕获请求异常如网络错误、404等这是编写健壮爬虫的好习惯。response.raise_for_status()会在状态码不是200时抛出异常。3.3 第三步解析与提取——BeautifulSoup大显身手拿到HTML字符串后交给BeautifulSoup解析。if html_content: soup BeautifulSoup(html_content, html.parser) # 使用我们之前观察到的规律每个电影条目都在 classitem 的div里 movie_items soup.find_all(div, class_item) for item in movie_items: # 在每个条目里查找电影名。注意豆瓣Top250页面的中文名在第一个classtitle的span里 title_tag item.find(span, class_title) # 查找评分 rating_tag item.find(span, class_rating_num) # 防止有些条目可能缺少信息做一下判断 title title_tag.text if title_tag else 未找到片名 rating rating_tag.text if rating_tag else 无评分 print(f电影{title} 评分{rating})这段代码已经可以运行并打印出第一页25部电影的名称和评分了。soup.find_all()是核心方法它找到所有符合条件的标签。find()则只找第一个。class_参数后面有个下划线是因为class是Python的关键字所以BeautifulSoup用class_来代表HTML的class属性。3.4 第四步处理翻页与数据存储豆瓣Top250有10页我们需要爬取所有页面。观察网址规律第一页是top250第二页是top250?start25第三页是top250?start50... 规律是start(页码-1)*25。import time base_url https://movie.douban.com/top250 headers { ... } # 同上 all_movies [] # 用一个列表来存储所有电影信息 for page in range(0, 10): # 0到9共10页 start page * 25 url f{base_url}?start{start} print(f正在抓取第{page1}页: {url}) try: response requests.get(url, headersheaders) response.raise_for_status() response.encoding response.apparent_encoding soup BeautifulSoup(response.text, html.parser) items soup.find_all(div, class_item) for item in items: title_tag item.find(span, class_title) rating_tag item.find(span, class_rating_num) # 还可以提取其他信息比如简介、评价人数等 # comment_tag item.find(div, class_star).find_all(span)[-1].text movie_info { title: title_tag.text if title_tag else N/A, rating: rating_tag.text if rating_tag else N/A, # comment: comment_tag } all_movies.append(movie_info) # 礼貌性延时避免请求过快给服务器造成压力 time.sleep(2) except requests.RequestException as e: print(f抓取第{page1}页时出错{e}) continue print(f共抓取到{len(all_movies)}部电影信息。)数据抓取到列表里后我们需要把它存下来。最常用的方式是存为CSV或JSON文件方便用Excel或后续的Python程序如pandas进行分析。import csv import json # 保存为CSV with open(douban_top250.csv, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnames[title, rating]) writer.writeheader() writer.writerows(all_movies) # 保存为JSON with open(douban_top250.json, w, encodingutf-8) as f: json.dump(all_movies, f, ensure_asciiFalse, indent2) print(数据已保存至 douban_top250.csv 和 douban_top250.json)4. 从能跑到跑得稳爬虫工程化与反爬应对策略上面的例子是一个理想化的教学场景。真实世界的网站往往设有各种障碍。让你的爬虫从“能跑”到“跑得稳、跑得久”需要关注以下几点。4.1 构建健壮的请求会话使用requests.Session()可以建立一个会话它会在多次请求间自动保持某些参数如cookies并且能复用底层的TCP连接提升效率。session requests.Session() session.headers.update(headers) # 为整个会话设置统一的请求头 response session.get(url) # 后续请求可以直接用 session.get/post4.2 处理常见的反爬机制User-Agent检测 我们已经做了伪装。更进一步可以准备一个User-Agent列表每次请求随机选取一个。请求频率限制 这是最基本的道德和技术要求。在循环请求中一定要加time.sleep()比如time.sleep(random.uniform(1, 3))随机休眠1-3秒。过于频繁的请求等同于攻击。IP封锁 如果加了延时还被封IP就需要考虑使用代理IP。使用方式很简单proxies { http: http://your_proxy_ip:port, https: https://your_proxy_ip:port, } response requests.get(url, headersheaders, proxiesproxies)但免费代理的稳定性极差自己搭建或购买可靠的代理服务是商业化爬虫的必经之路。验证码 遇到验证码小规模爬虫可以手动处理或者接入打码平台。大规模情况下需要研究验证码的破解如图像识别但这通常涉及更复杂的技术和道德考量。登录与Cookie 对于需要登录的网站先用浏览器手动登录然后从开发者工具的Network标签里复制出Cookie放到请求头里。或者用Selenium模拟登录过程获取登录后的Cookie再交给Requests使用。4.3 异常处理与日志记录一个工业级的爬虫必须有完善的异常处理和日志。import logging logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[logging.FileHandler(spider.log), logging.StreamHandler()]) try: response session.get(url, timeout10) # 设置超时 response.raise_for_status() except requests.exceptions.Timeout: logging.error(f请求超时: {url}) except requests.exceptions.HTTPError as e: logging.error(fHTTP错误 {e.response.status_code}: {url}) except Exception as e: logging.error(f未知错误: {e})良好的日志能让你在爬虫运行数小时后依然能清晰定位哪里出了问题。4.4 解析策略的容错性不要假设网页结构永远不变。你的解析代码要足够健壮。# 不推荐的脆弱写法 title soup.find(span, class_title).text # 如果找不到这里会抛出AttributeError # 推荐的健壮写法 title_tag soup.find(span, class_title) if title_tag: title title_tag.text.strip() # 用strip()去掉空白字符 else: title N/A logging.warning(f在页面中未找到标题标签)或者使用try...except包裹或者使用get_text()方法如果标签存在则返回文本否则返回空字符串。5. 进阶之路当RequestsBS4力不从心时当你遇到以下情况就需要请出更强大的工具了页面内容由JavaScript动态生成 用Requests获取的HTML里没有数据。此时可以寻找隐藏的API 在开发者工具的Network标签里过滤XHR或Fetch请求找到真正返回数据的那个接口地址。然后用Requests直接请求这个接口通常返回JSON格式效率更高。这是首选方案。使用Selenium/Playwright 让程序控制浏览器渲染页面等数据加载完成后再获取HTML。虽然慢但能解决几乎所有前端渲染的问题。from selenium import webdriver from selenium.webdriver.common.by import By driver webdriver.Chrome() # 需要先下载对应浏览器的驱动 driver.get(url) # 等待某个元素出现 element WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, item)) ) html driver.page_source # 之后就可以用BeautifulSoup解析html了 driver.quit()大规模分布式爬取 当需要爬取的数据量极其庞大数千万页面时单机爬虫在速度和稳定性上都不够。这时需要考虑使用Scrapy框架。Scrapy是一个为爬虫而生的异步框架它内置了请求调度、去重、管道处理数据清洗、存储等功能可以轻松地扩展到多台机器上运行是构建大型爬虫项目的首选。需要解析JavaScript执行结果 除了Selenium还可以使用Pyppeteer或Playwright它们提供了比Selenium更现代、性能更好的无头浏览器控制接口。6. 法律与道德的边界做一个负责任的爬虫工程师这是最重要的一节。技术本身无罪但使用技术的方式有对错。尊重robots.txt 这是网站管理员与爬虫之间的基本协议。访问https://example.com/robots.txt可以查看该网站对爬虫的限制。明确禁止爬取的目录就不要去碰。控制访问频率 这是最基本的网络礼仪。你的爬虫不应该影响网站的正常服务。添加显著的延时如每秒请求数低于1避免并发大量请求。识别并遵守使用条款 很多网站的用户协议里会明确禁止爬虫或自动化访问。虽然法律效力因地区而异但违反协议是不道德且有风险的。只爬取公开数据 切勿尝试爬取需要登录才能访问的非公开数据、个人隐私数据如用户手机号、邮箱、或受版权严格保护的内容。数据用途 将爬取的数据用于个人学习、研究或公益目的风险较低。如果用于商业盈利务必进行法律风险评估。知识产权 爬取的数据可能涉及数据库权或版权。对数据进行实质性加工、分析后形成新的成果比单纯复制原始数据风险更低。我个人的经验是在开始一个爬虫项目前先问自己三个问题我的爬取行为会拖慢甚至搞垮对方的服务器吗我爬取的数据会侵犯个人隐私或商业秘密吗我使用这些数据的方式会伤害到数据提供方吗如果任何一个答案是“可能”那就停下来重新设计你的方案或者放弃。
返回列表