"每天手动检查 3,000个商品价格。" — 即使听到这句话,也没有人会感到无所谓。实际上,许多国内电子商务公司都通过Python爬虫自动化了这项工作,而且开始非常简单。本文从网页抓取的基础知识到实际遇到的真实问题 — 都以实际运行的代码进行了总结。
目录
- 什么是网页抓取?
- Python抓取基础 — requests + BeautifulSoup
- 动态页面抓取 — Selenium和Playwright
- 常见的抓取问题
- 抓取与法律问题 — 必须了解的事项
- 大规模抓取的现实 — 维护地狱
- 自制还是专业服务 — 何时选择何种?
什么是网页抓取?
网页抓取(Web Crawling) 是程序自动访问网页并提取所需数据的技术。在实际工作中,这个术语通常与网页爬取(Web Scraping) 混用。
[网页抓取基本流程图:HTTP请求 → 接收HTML → 解析 → 数据提取 → 存储](images/seo1-crawling-flow.png)
它可以用在哪里?适用范围比想象中广泛。
- 价格监控 — 自动收集竞争对手商城的3,000个商品价格,追踪最低价
- 市场研究 — 一次性从Naver购物、Coupang等网站收集产品信息、评论、评分数据
- 潜在客户生成 — 大量收集潜在客户联系方式、企业信息用于营销
- 内容监控 — 实时跟踪新闻、社交媒体、社区中特定关键词
- 数据分析 — 构建大规模数据集,如房地产价格、招聘信息、学术数据等
Python在抓取中被广泛使用的原因是显而易见的。因为有丰富的库,如BeautifulSoup、Selenium、Playwright,语法直观,可以快速创建原型。
Python抓取基础 — requests + BeautifulSoup
这是最基本的组合。使用requests获取HTML,使用BeautifulSoup解析所需数据。对于静态HTML页面,这就足够了。
安装
pip install requests beautifulsoup4
基本示例:收集新闻标题
import requests
from bs4 import BeautifulSoup
# 1. 웹 페이지 HTML 가져오기
# requests.get()으로 HTTP GET 요청을 보냅니다
url = "https://news.ycombinator.com/"
# 2. User-Agent 헤더 설정
# 헤더 없이 요청하면 봇으로 판단해 차단하는 사이트가 많습니다
# 실제 브라우저처럼 보이도록 User-Agent를 설정합니다
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
response = requests.get(url, headers=headers)
# response.raise_for_status() # HTTP 에러 시 예외 발생 (선택)
# 3. BeautifulSoup으로 HTML 파싱
# html.parser는 파이썬 내장 파서 — 별도 설치 불필요
soup = BeautifulSoup(response.text, "html.parser")
# 4. CSS 선택자로 원하는 요소 추출
# .titleline > a → class="titleline" 하위의 <a> 태그 (뉴스 제목 + 링크)
titles = soup.select(".titleline > a")
for i, title in enumerate(titles, 1):
print(f"{i}. {title.text}")
print(f" 링크: {title['href']}")
这段代码只需20行,就可以收集Hacker News的所有标题和链接。这就是所谓的Python抓取的入门门槛之低。
多页面抓取(分页)
在实际工作中,很少只抓取一页。了解如何遍历多个页面的模式,就可以应用于大多数列表型网站。
import requests
from bs4 import BeautifulSoup
import time
# 페이지 번호를 URL에 넣는 패턴 — 대부분의 리스트 페이지가 이 구조
base_url = "https://example-blog.com/posts?page={}"
all_posts = []
for page in range(1, 11): # 1~10페이지 순회
response = requests.get(base_url.format(page), headers=headers)
soup = BeautifulSoup(response.text, "html.parser")
# 각 게시글 카드에서 제목, 날짜, URL 추출
posts = soup.select(".post-item")
for post in posts:
all_posts.append({
"title": post.select_one(".post-title").text.strip(),
"date": post.select_one(".post-date").text.strip(),
"url": post.select_one("a")["href"]
})
# 서버 부하 방지를 위한 요청 간격 설정
# 1초도 짧을 수 있음 — 대상 사이트 robots.txt의 Crawl-delay 확인 권장
time.sleep(1)
print(f"총 {len(all_posts)}개 포스트 수집 완료")
提示: 使用
time.sleep()设置请求间隔是网页抓取的基本礼仪。请求太快会给服务器带来负担,直接导致IP被封锁。通常1~3秒的间隔是安全的。
动态页面抓取 — Selenium和Playwright
如今许多网站都使用JavaScript渲染内容。在基于React、Vue、Next.js的SPA(单页应用) 中,即使使用requests获取HTML,也只会得到空的<div id="root"></div> — 因为数据是在JavaScript执行后加载的。
这时就需要浏览器自动化工具。实际上启动真实浏览器执行JavaScript,然后从渲染结果中提取数据。
[静态抓取 vs 动态抓取比较:requests只接收服务器HTML,Selenium/Playwright访问JS渲染后的DOM](images/seo1-static-vs-dynamic.png)
Selenium抓取示例
Selenium是最早的浏览器自动化工具,与抓取相关的资料最丰富。
pip install selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 1. 크롬 브라우저를 헤드리스(화면 없이) 모드로 실행
# 서버 환경에서는 화면이 없으므로 헤드리스 모드 필수
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
try:
# 2. 대상 페이지 접속
driver.get("https://example-spa.com/products")
# 3. JavaScript 렌더링이 끝날 때까지 최대 10초 대기
# WebDriverWait는 요소가 나타나면 즉시 다음 단계로 진행
# 10초 안에 안 나타나면 TimeoutException 발생
WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".product-card"))
)
# 4. 렌더링된 DOM에서 데이터 추출
products = driver.find_elements(By.CSS_SELECTOR, ".product-card")
for product in products:
name = product.find_element(By.CSS_SELECTOR, ".product-name").text
price = product.find_element(By.CSS_SELECTOR, ".product-price").text
print(f"{name}: {price}")
finally:
# 5. 브라우저 종료 — 안 닫으면 메모리 누수 발생
driver.quit()
Playwright抓取示例(2026推荐)
Playwright是微软开发的下一代浏览器自动化库。比Selenium更快、更稳定,内置自动等待(auto-wait) 功能,无需像WebDriverWait那样的样板代码。截至2026年,如果是新项目,推荐使用Playwright。
pip install playwright
playwright install chromium # 브라우저 바이너리 자동 다운로드
from playwright.sync_api import sync_playwright
# Playwright는 컨텍스트 매니저로 리소스를 자동 관리
with sync_playwright() as p:
# 1. Chromium 브라우저를 헤드리스 모드로 실행
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# 2. 대상 페이지 접속
page.goto("https://example-spa.com/products")
# 3. Playwright는 자동으로 요소가 나타날 때까지 대기
# 별도의 WebDriverWait 코드가 필요 없음 — 훨씬 깔끔합니다
cards = page.locator(".product-card").all()
for card in cards:
name = card.locator(".product-name").text_content()
price = card.locator(".product-price").text_content()
print(f"{name}: {price}")
# 4. 브라우저 종료
browser.close()
Selenium vs Playwright — 该用哪个?
[Selenium vs Playwright比较信息图](images/seo1-selenium-vs-playwright.png)
| 比较项目 | Selenium | Playwright |
|---|---|---|
| 速度 | 一般 | 一般认为比Selenium更快 |
| 自动等待 | 需手动设置 | 内置 |
| 浏览器支持 | Chrome, Firefox, Edge, Safari | Chromium, Firefox, WebKit |
| 网络拦截 | 有限 | 默认提供 |
| 学习资料 | 非常丰富(10年+历史) | 迅速增长中 |
| 推荐情况 | 传统项目,简单自动化 | 新项目,大规模抓取 |
常见的抓取问题
阅读到这里,你可能会觉得“抓取没什么大不了的吧?”。但实际上,当你尝试进行Python抓取时,你会发现比编写代码更困难的问题等待着你。我总结了大多数初次尝试构建抓取器的开发人员遇到的5个问题。
1. IP封锁
如果同一IP频繁请求,大多数网站都会封锁。应对方法是代理轮换和调整请求间隔,但问题在于成本。优质住宅代理每GB价格在5~15美元,月基本费用在50~500美元。加上代理质量监控、更换被封IP等管理成本,这绝非小数。
2. 验证码和机器人检测
Cloudflare、PerimeterX、Akamai Bot Manager、DataDome — 机器人防护解决方案越来越精密。reCAPTCHA v3分析鼠标移动、滚动模式、按键速度等。使用验证码解决服务(如2Captcha)的成本约为每次1~5分(取决于类型),但每天10万次就需要超过600万韩元。除了成本外,速度和成功率的管理也不容易。
3. 动态渲染和无限滚动
需要JavaScript渲染的网站越来越多。因为需要启动浏览器实例,每页占用300~500MB内存,比静态抓取慢5~10倍。要同时运行50个浏览器,至少需要16GB RAM服务器,云端基础设施费用约15~30万韩元。
4. 网站结构更改
抓取目标网站更改设计或HTML结构,抓取器会立即失效。活跃的网站每2~3个月就会更改结构。需要保持监测变化 → 修改代码 → 测试 → 部署的周期,并且如果有20个目标网站,每年就需要进行80~120次维护。
5. 数据清洗
期望收集到的数据是干净的是不现实的。每个网站的编码(UTF-8、EUC-KR)不同,日期格式(2026.01.30 vs 2026-01-30 vs Jan 30, 2026)不同,相同信息以完全不同的方式呈现。根据经验,数据清洗工作会额外占用30~50%的收集时间。
抓取与法律问题 — 必须了解的事项
尽管技术上抓取很容易,法律上是一个灰色地带。"能抓取"和"可以抓取"是完全不同的问题。如果是商业目的的抓取,务必确认以下三点。
robots.txt — 抓取的基本规则
robots.txt是网站所有者声明“请不要抓取这些路径”的文件。尽管对其法律约束性存在争议,但实际上是行业标准。忽略这些规则的抓取可能在诉讼中起到不利作用。
# 예시: https://example.com/robots.txt
User-agent: *
Disallow: /private/
Disallow: /api/
Crawl-delay: 2 # 요청 간격 2초 이상 유지 요청
检查方法很简单。只需在目标URL后面加上/robots.txt即可(例如:https://naver.com/robots.txt)。被Disallow声明的路径应该排除在抓取范围之外,如果有Crawl-delay,则应遵守相应间隔。
个人信息保护法 — 最需要注意的领域
韩国的个人信息保护法原则上要求在收集个人信息时获得信息主体的同意。如果抓取的数据包含姓名、电话号码、电子邮件等可识别个人身份的信息,那么存储或使用这些数据本身可能是违法的。
实际注意事项:
- 即使是公开网页,也不能未经同意收集或使用个人信息
- 特别是联系方式、社交媒体资料、用户评论(包括昵称)需要小心
- 针对欧盟服务的情况适用GDPR — 违反可能导致全球销售额的最高4%罚款
- 在韩国,个人信息保护委员会的制裁越来越严格
现实建议: 仅收集价格、产品规格、市场数据等非个人信息是最安全的。如果需要包含个人信息的数据,务必首先进行法律审查。
版权法 — 数据本身的权利
发布在网页上的文本、图像、视频等大多数受到版权保护。虽然抓取数据本身是技术行为,但如果直接再发布或商业使用抓取的内容,则可能构成侵权。
判例和标准:
- 事实信息(价格、数字数据) 通常不受版权保护
- 创作物(文章、评论、图片) 受版权保护
- 如果整个数据库被完全复制,可能构成不正当竞争行为
- 美国的hiQ Labs v. LinkedIn案例(2022年)认为公开个人资料抓取不违反CFAA,但LinkedIn后来以违反使用条款为由提起了另一项诉讼,并最终达成和解。即使是公开数据,也可能受到使用条款和合同法的限制,因此必须检查各国法律和目标网站的ToS。
[抓取法律检查清单: 检查robots.txt → 是否包含个人信息 → 可能侵犯版权 → 检查使用条款](images/seo1-legal-checklist.png)
总结: 在开始抓取之前,请务必检查以上四点:① 检查robots.txt,② 是否包含个人信息,③ 收集数据的使用范围,④ 目标网站的使用条款。如果没有把握,请咨询法律意见,这是最安全的投资。
大规模抓取的现实 — 维护地狱
在小型项目中,只需一个Python脚本就足够了。但是,如果需要持续运营抓取作业,情况完全不同。
要运营大规模网页抓取系统,需要以下内容:
- 基础设施 — 服务器、调度器(Airflow、Celery等)、队列系统、数据库
- 代理管理 — 购买、轮换、质量监控数百至数千个代理(月费50~500美元)
- 错误处理 — 重试逻辑、故障通知、自动恢复
- 数据管道 — 自动化收集 → 清洗 → 加载 → 验证
- 监控 — 抓取器状态、收集数据质量、目标网站更改检测
- 法律合规 — robots.txt、个人信息保护法、版权法持续审查
[大规模抓取架构: 调度器 → 抓取池 → 代理轮换 → 数据管道 → 存储库](images/seo1-large-scale-architecture.png)
考虑到实际成本 — 一个开发人员制作抓取器大约需要2周(人工成本30~40万韩元),之后每月需要40~60小时(人工成本20~30万韩元)。如果抓取目标增加到10个、20个,抓取基础设施管理本身就成为全职工作。加上代理、服务器、验证码解决成本,每月500万韩元以上用于抓取的情况也并不少见。
"制作抓取器很容易。保持其稳定运行才是真正的工作。"
— 任何运营过抓取系统的开发人员都会同意这一点。
自制还是专业服务 — 何时选择何种?
| 情况 | 推荐方法 |
|---|---|
| 学习目的、一次性收集 | requests + BeautifulSoup |
| 动态网站、小型项目 | Playwright或Selenium |
| 商业运营、多个网站、稳定性必需 | 专业抓取服务 |
学习Python抓取是作为开发人员的有价值投资。对于简单的数据收集或原型,本文介绍的工具足够了。
但一旦抓取成为业务核心数据管道,直接制作和维护成本(每月500万韩元以上)与专业服务成本进行冷静比较是有必要的。开发资源应该专




