The essential points from this guide -- each one is explained in detail below.
网页抓取把发请求、解析数据、存储结果这三步自动化,让原本需要人工复制的信息变成结构化数据。
价格监控、市场调研、销售线索收集是最常见的商业用途,跨境电商团队常用它追踪海外平台的竞品价格。
规模化抓取几乎都离不开代理,单个IP发太多请求很快会被限流或直接封锁。
Python是抓取任务的主流语言,requests/httpx负责发请求,BeautifulSoup或Scrapy负责解析,Playwright应对需要执行JavaScript的页面。
存储数据时给每一行加上时间戳,否则只能看到当前值,没法追踪价格或内容随时间的变化。
网页抓取的流程其实很简单:程序向目标网址发送HTTP请求,拿到返回的HTML或JSON,从里面提取出你需要的字段——价格、商品名称、评论、联系方式——最后存成CSV、JSON或者数据库里的一条记录。往简单了说,这和人工打开网页复制数据是同一件事,只是换成机器在做,速度快了几个数量级。
对跨境电商团队来说,最常见的应用是盯着海外平台上的竞品价格和库存变化:与其每天手动打开几十个商品页面对比价格,不如让脚本按固定频率自动抓取,把变化直接记录下来。
网站会限制单个IP的请求频率,同一个IP在一小时内发出几千次请求,很快会被限流甚至直接封锁,这是几乎所有目标网站的默认防护。把请求通过大量不同的IP轮换转发,能让每一次请求看起来都来自不同的访问者,这是维持稳定成功率的关键。
对设有反爬系统的目标网站,住宅代理是更稳妥的选择,因为它的IP来自真实家庭网络,信任等级比数据中心IP高得多;防护较弱的普通网站,成本更低的数据中心代理通常也够用。
Python在网页抓取领域占绝对主流。标准工具链是requests或httpx负责发送HTTP请求,BeautifulSoup或lxml负责解析HTML,需要完整爬虫框架时用Scrapy。遇到依赖JavaScript渲染内容的页面,Playwright和Puppeteer这类无头浏览器工具是标准做法,它们会真正在浏览器引擎里跑完页面的JavaScript,再把渲染完成的HTML交给你处理。Node.js生态里,cheerio负责解析HTML,got或axios负责发请求,是另一套常见组合。
刚入门的团队通常从一个脚本、几个目标页面开始,先确认解析逻辑没问题,再逐步加上代理、重试和定时调度。一上来就想同时搞定大规模抓取、代理轮换和数据存储,是很多抓取项目还没上线就卡住的常见原因。
一个基础的抓取脚本只需要三步:请求页面、解析HTML、提取字段。下面是一个从页面里提取商品标题的最简示例:
import requests
from bs4 import BeautifulSoup
response = requests.get('https://example.com/products', timeout=30)
soup = BeautifulSoup(response.text, 'lxml')
titles = soup.find_all('h2', class_='product-title')
for title in titles:
print(title.get_text(strip=True))requests.get()负责把原始HTML下载下来,BeautifulSoup把这段HTML转成可以查找的对象,find()返回第一个匹配结果,find_all()返回页面上所有匹配结果组成的列表。
解析之前一定要先检查响应状态:response.status_code等于200说明请求成功,如果是403或429,说明目标网站已经拦截或限流了这次请求,而不是正常返回了页面内容。把解析步骤包在对response.ok的判断里,能让被拦截的请求干净地失败,而不是拿着空白或异常的HTML去解析导致脚本崩溃。
网站对抗自动化流量常用的手段主要是这几种:按IP限速、检查请求头和User-Agent、TLS指纹识别,以及CAPTCHA验证。一个脚本如果这四项全都不处理,在有像样反爬防护的网站上很快就会被拦下来。
限速最容易触发。短时间内从同一个IP发出远超真人操作速度的请求,是脚本被封锁的头号原因,放慢速度、给请求间隔加上随机延迟、用代理池把请求分散到多个IP上,是最直接的应对办法。
请求头检查会盯上那些只带了简单User-Agent、缺少Accept-Language或Referer这类真实浏览器必带请求头的脚本。TLS指纹识别则是比对连接握手的特征——用requests库发出的请求,握手特征和真实Chrome浏览器不一样,一些反爬系统会直接根据这个差异判断出流量来自脚本;Playwright、Puppeteer这类真实浏览器引擎驱动的工具能规避这个问题。CAPTCHA通常在前面几项信号叠加到一定风险阈值后才会出现,住宅代理因为IP本身信任等级更高,能明显降低CAPTCHA出现的频率。
解析完的数据通常存成三种格式之一:CSV适合导入表格直接查看的简单结果;JSON更适合评论列表这类结构不固定的嵌套数据;需要长期反复运行、追踪数值变化的抓取任务,用SQLite或PostgreSQL这类数据库更合适。不管用哪种格式,给每一行数据加上时间戳都很重要——没有时间戳的价格或内容,只能告诉你现在的数值,没法看出它是涨了还是跌了,而追踪变化往往才是团队做抓取的真正目的。
生产环境的抓取脚本还需要处理失败请求,超时、连接中断、被拦截的响应在长时间运行的任务里很常见。用try/except包住每次请求,配合逐次拉长的重试间隔(指数退避),能让一次失败的请求不至于中断整个抓取任务:
import time
def fetch_with_retry(url, proxies, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.get(url, proxies=proxies, timeout=30)
if response.ok:
return response
except requests.RequestException:
pass
time.sleep(2 ** attempt)
return None这段代码最多重试三次,等待时间依次是1秒、2秒、4秒,全部失败后返回None,调用方可以记录下这个失败的URL再继续处理下一个,而不是让整个任务因为一次请求失败就崩溃退出。记录失败时留下状态码:连续出现429说明该放慢速度或加更多代理IP了,连续出现403往往说明这个IP已经被针对性拦截,需要换一个IP或换一种代理类型。
Ready to put this into practice? 浏览住宅代理产品
KnoxProxy Research Team · 技术内容团队
在反机器人系统、网页抓取和IP路由领域拥有10年以上经验的网络工程师和代理基础设施专家。
Ethically sourced residential IPs across 195 countries. Instant activation, 14-day money-back guarantee.