尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Selenium+代理IP绕过京东反爬:商品数据采集完整实战
先聊点实在的京东是当前国内主流电商里反爬投入最舍得下本的一家我测试过不少采集方案requests 直接怼接口的玩法基本活不过两轮你能想到的 UA、Cookie、签名、加密参数它全都用上了。就算你有本事把参数补齐紧接着等你的还有滑块验证和 IP 维度频控。这套东西堆下来很多做电商数据分析和市场调研的朋友会被拦在门外最后只能去买第三方数据成本高不说字段还不一定全。我自己的做法是用 Selenium 模拟真实浏览器操作再配合代理 IP 把请求分散到不同出口实测能够绕过绝大多数反爬限制稳定拿到商品标题、价格、店铺、评论数这些核心字段。这篇文章把我这套完整方案拆开讲地址选择、参数配置、元素定位、异常兜底一次性说清楚代码可以直接拷下来改着用。1. 京东反爬机制拆解先搞清楚对方在拦什么1.1 京东常用的四层反爬防线很多新手上来就写代码写完发现被封了然后到处问为什么其实问题就出在没先搞明白京东到底在拦什么。我拆过它的请求链路至少存在四层防护。第一层是基础请求头校验。UA、Referer、Accept-Language 这些字段会被逐一检查缺一个或者值不对都可能直接拒绝响应。很多爬虫死在第一步就是因为只带了默认 UA。第二层是 Cookie 与登录态风控。未登录状态下能拿到的数据有限登录之后 Cookie 里会埋的字段更多而且服务端会校验 Cookie 的生成时间、使用频率和对应的 IP 是否匹配。同一个 Cookie 短时间内频繁换 IP或者一个 IP 短时间带大量不同 Cookie都会被标记为异常。第三层是行为检测。京东会在页面里埋点统计你的鼠标轨迹、滚动行为、点击间隔、页面停留时间。如果是 Selenium 默认配置启动的浏览器window.navigator.webdriver 这个属性是 true脚本一执行就被识别。这一层的隐蔽性很强很多人代码写得没毛病但就是被限流原因就在这。第四层是 IP 维度频控。单个 IP 在单位时间内的请求次数会被精确统计超过阈值直接返回滑块验证或者干脆把你的 IP 拉进黑名单一段时间。这一层是所有爬虫方案里最难绕的因为不管你代码写得再漂亮IP 是同一个人家一眼就能看穿。所以你要做的不是挑战某一个反爬点而是从整体上模拟一个真实用户的访问行为。Selenium 解决的是浏览器指纹和 JS 渲染的问题代理 IP 解决的是入口分散的问题两者配合才能形成一套比较完整的绕反爬方案。1.2 方案选型为什么是 Selenium 代理IP 的组合我先说结论如果你只想抓商品详情页的少量数据用 requests 手工维护 Cookie 也不是不行但如果你想批量抓搜索页、翻多页、轮换关键词Selenium 代理 IP 是综合成本最低的方案。选择 Selenium 有几个很实际的理由。第一京东的前端页面大量使用 JS 动态渲染商品列表、价格、促销信息大多是通过异步接口加载后再拼接到 DOM 里的。requests 拿到的是空壳 HTML里面根本没有商品数据还得去逆向分析它的异步接口、加密参数、签名逻辑这个工作量非常大。Selenium 是直接驱动真实浏览器页面渲染完之后 DOM 里就是完整数据你只需要做元素定位。第二Selenium 自带浏览器环境指纹信息是真实的不需要去处理 TLS 指纹、HTTP/2 指纹这类底层问题。requests 的 TLS 指纹和真实浏览器有明显差异服务端可以通过 JA3 这类技术识别出来Selenium 没有这个烦恼。第三Selenium 生态成熟定位元素、等待渲染、模拟滚动、处理弹窗这些功能都有现成的方法代码写起来直观调试也方便。虽然它比 requests 慢但对于商品数据这种更新频率不高的场景速度完全够用。至于代理 IP我把它理解为给每个请求换一个出口身份。1.3 这套方案的边界与适用场景我也把丑话说在前面Selenium 代理 IP 并不是万能钥匙。它最大的劣势是速度和资源消耗一个浏览器实例要占几百 MB 内存并发做不了太高。如果你要抓千万级数据应该考虑逆向京东的移动端接口或者用 Playwright 的 CDP 协议配合请求拦截那是另一套更复杂的玩法。这套方案适合的场景是中小规模数据采集比如跟踪竞品价格、分析类目销量趋势、做选品调研每天几千到几万条数据的量级。再往上走我建议直接对接正规数据服务商省心省力还合规。还有一个必须强调的前提这篇文章的技术方案仅供学习交流真实抓取前请务必阅读京东的 robots 协议和用户协议控制抓取频率不要对目标网站造成压力。技术本身没有对错但使用技术的边界得由自己把握。2. 环境准备与代理IP接入2.1 环境依赖安装附版本对照开始写代码之前先把环境装利索。我用的是 Python 3.10配合 Selenium 4.x 和 Chrome 浏览器这套组合目前兼容性最好。第一步安装 Selenium直接 pip 安装。pip install selenium第二步下载 ChromeDriver。这里有个版本匹配的问题ChromeDriver 的主版本号必须和 Chrome 浏览器的主版本号一致否则浏览器起不来。比如你本地 Chrome 是 120 版本就要下载 120 版本的 ChromeDriver。第三步把 ChromeDriver 所在目录加入系统 PATH或者在代码里直接用 Service 指定路径我更喜欢后者更可控。from selenium.webdriver.chrome.service import Service service Service(/path/to/chromedriver) driver webdriver.Chrome(serviceservice, optionsoptions)如果你用的是 Selenium 4.6 以上版本情况会简单很多它内置了 Selenium Manager会自动检测 Chrome 版本并下载对应的 ChromeDriver不需要手工管理。装完依赖之后先用一行最简单的代码验证环境是否正常。from selenium import webdriver driver webdriver.Chrome() driver.get(https://www.example.com) print(driver.title) driver.quit()能打印出网页标题说明环境没问题可以进入下一步。2.2 代理IP怎么选短时代理、隧道代理与质量评估代理 IP 是这套方案里最容易踩坑的环节我见过太多人买了一堆便宜代理结果请求全部超时以为是代码问题折腾半天才发现是代理质量太差。市面上常见的有两类短时代理和隧道代理。短时代理是给你一个 IP 列表每个 IP 有一定存活时间从几分钟到几十分钟不等你需要自己写代码轮换。优点是单价低缺点是维护成本高要频繁检测 IP 存活状态失效了要自动切换。隧道代理是一个固定域名你请求的时候把代理地址指向这个域名服务端会自动帮你调度后端的 IP 池你不需要关心具体用的是哪个 IP。优点是完全不用自己写轮换逻辑稳定性好缺点是要走代理服务商的 DNS 解析延迟略高价格也贵一些。我的建议是爬京东这种反爬严格的站点尽量用隧道代理。因为京东的频控规则是动态调整的一旦某个 IP 被拉黑你要能快速切换隧道代理天然就是动态 IP 池切换效率比手工轮换高很多。选择代理服务商时重点关注几个指标IP 池的规模、可用率低于 95% 的直接不考虑、响应延迟、如果涉及登录场景地域是否和你使用的账号匹配。很多服务商提供 API 接口用来提取 IP你也可以先充一点钱做个小规模测试跑个几百个请求看看成功率再决定是否批量采购。2.3 把代理注入Selenium 的三种方式代理 IP 准备好了接下来要想办法让 Selenium 的流量走代理出口。一共有三种常见做法。第一种是启动参数方式也是最推荐的方式。在创建浏览器实例时通过 add_argument 添加代理配置这样整个浏览器进程的所有请求都会走代理。from selenium import webdriver from selenium.webdriver.chrome.options import Options options Options() options.add_argument(--proxy-serverhttp://username:passwordip:port) driver webdriver.Chrome(optionsoptions)如果代理不需要认证就把用户名密码部分去掉直接写 IP 和端口。第二种是使用 Chrome DevTools Protocol 动态配置。这种方式适合你已经启动了浏览器、不想重启的场景通过 CDP 命令修改网络层配置。driver.execute_cdp_cmd(Network.enable, {}) driver.execute_cdp_cmd(Network.setExtraHTTPHeaders, { headers: { Proxy-Authorization: Basic base64.b64encode( busername:password ).decode(utf-8) } })第三种是配合第三方库托管代理比如使用 selenium-wire它可以让你在 Selenium 中像 requests 一样使用 proxies 参数但需要额外安装证书做一些中间人操作配置复杂度高我不推荐新手用。按我的习惯第一、第二种组合着来启动参数设全局代理如果运行过程中遇到某个 IP 被封就用 CDP 方式动态切换代理不用重启浏览器。3. 绕过反爬的完整实操从启动浏览器到落库3.1 初始化带代理的浏览器实例环境就绪代理就绪接下来就是写代码了。我先给出一个带完整配置的浏览器初始化函数把能想到的反检测参数全部加上。import random from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service def create_driver(proxy_host, proxy_port, proxy_user, proxy_pass): options Options() # 忽略证书错误 options.add_argument(--ignore-certificate-errors) # 关闭自动化控制提示 options.add_experimental_option(excludeSwitches, [enable-automation]) options.add_experimental_option(useAutomationExtension, False) # 去掉 webdriver 指纹 options.add_argument(--disable-blink-featuresAutomationControlled) # 设置窗口大小模拟真实用户 options.add_argument(--window-size1920,1080) # 常见的浏览器参数 options.add_argument(--disable-gpu) options.add_argument(--no-sandbox) options.add_argument(--langzh-CN) options.add_argument( user-agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 ) # 代理配置 proxy_url fhttp://{proxy_user}:{proxy_pass}{proxy_host}:{proxy_port} options.add_argument(f--proxy-server{proxy_url}) driver webdriver.Chrome(optionsoptions) # 覆盖 navigator.webdriver 属性 driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, { get: () undefined }); }) return driver这段代码里的几个关键点要解释一下。--disable-blink-featuresAutomationControlled 是用来去掉 Chrome 的自动化控制标记配合后面的 CDP 脚本覆盖 navigator.webdriver两道保险双管齐下。窗口大小设成 1920x1080 是因为很多反爬系统会把非标准窗口尺寸作为一个异常信号。UA 设置为真实浏览器的 UA不要让 Selenium 暴露默认值。从代码可以看出Selenium 反检测的核心思路就是抹平浏览器自动化特征让目标网站认为你就是一个普通用户在用 Chrome 上网。3.2 搜索页与翻页真正的难点在元素定位浏览器初始化之后接下来就是访问搜索页、定位商品元素、翻页。这一步代码本身不复杂真正的难点在于京东的页面结构比较乱尤其是标题里提到的下拉框它不是原生 select 元素而是 div ul li 组合模拟的自定义组件。先看怎么处理这类自定义下拉框。假设页面上有一个排序方式选择器HTML 结构大概是这样的div classcustom-select idsort-select div classselect-text综合排序/div ul classselect-list styledisplay: none; li>from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 点击展开下拉框 sort_select driver.find_element(By.CSS_SELECTOR, #sort-select) sort_select.click() # 等待下拉列表出现 list_items WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located( (By.CSS_SELECTOR, #sort-select .select-list li) ) ) # 点击目标选项 for item in list_items: if item.text.strip() 销量: item.click() break这种方案的逻辑是先点击触发列表展开然后等待 ul 下的 li 元素全部加载出来再遍历匹配文本内容。批量采集的时候这种选择器的问题在于京东的 class 命名经常带动态后缀每次刷新页面可能都不一样所以我自己习惯用 XPath 和文本匹配组合。定位页面上的商品元素时建议多用 CSS 选择器加属性匹配。京东的商品列表每个商品都是一个独立块里面有商品标题、价格、店铺、评论数等字段具体结构可能会随页面改版而变化所以代码里要写几个备用选择器一个失效了自动切换下一个。翻页部分我直接模拟点击下一页按钮同时加入随机延迟模拟真实用户的阅读节奏。import time import random def scroll_and_next(driver): # 模拟滚动页面 for _ in range(3): driver.execute_script(window.scrollBy(0, 500);) time.sleep(random.uniform(0.5, 1.5)) # 点击下一页 next_btn driver.find_element(By.CSS_SELECTOR, .pagination .next) next_btn.click() time.sleep(random.uniform(2, 4))随机延迟特别重要一个机器人要是每次请求间隔都精确到毫秒级等于在脸上写着我是脚本。3.3 解析商品字段标题、价格、店铺、评论数数据解析是爬虫的核心输出环节。拿到页面之后要从中提取出结构化字段。商品标题一般在商品链接的 a 标签里或者图片的 alt 属性里。价格数据比较麻烦京东的商品价格往往是通过异步接口加载的页面初始 HTML 里可能没有完整价格这时候需要等待价格元素渲染完成或者直接从接口返回中提取。店铺名称一般在商品卡片下方评论数和好评率通常在商品标题旁边。下面给出一段比较健壮的解析代码用多种策略兜底。def parse_product(driver): item {} # 标题优先取 title 属性其次取文本 title_selectors [ .p-name a em, .p-name a, .p-img img[alt] ] for selector in title_selectors: try: el driver.find_element(By.CSS_SELECTOR, selector) item[title] el.get_attribute(title) or el.get_attribute(alt) or el.text if item[title]: break except Exception: continue # 价格等待价格渲染多个备用类名 price_selectors [.p-price strong, .price, .p-price] for selector in price_selectors: try: price_el WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, selector)) ) text price_el.text.strip() if text: item[price] text break except Exception: continue # 店铺名和评论数同理用多个选择器兜底 # ... return item解析逻辑的通用原则是先用最精确的选择器失败就降级到更宽泛的选择器最后实在解析不到就跳过。没有人能保证页面结构永远不变所以解析代码要写成多级容错的形态。这里我补充一个重要技巧京东的商品链接里带 skuId这个 ID 是商品的唯一标识采集的时候一定要单独提取出来后续做去重、增量更新都靠它。获取 skuId 也简单从商品详情页的 URL 里正则匹配即可。import re sku_match re.search(rskuId[:](\d), driver.current_url) if sku_match: item[sku_id] sku_match.group(1)3.4 反爬触发识别与兜底策略不管前面准备工作做得多充分运行过程中总会遇到反爬触发的情况这很正常关键是程序要能快速识别并做出反应。最常见的反爬信号有三种。第一是页面出现滑块验证特征是有个滑块组件或者 iframe 嵌入的验证页面第二是页面跳转到登录页或者风险验证页URL 不再是正常的商品列表页第三是请求到的页面内容里商品数量为 0或者直接返回空白。我习惯在代码里写一个检测函数每次页面跳转后先判断一下是否正常。def check_blocked(driver): current_url driver.current_url page_text driver.page_source # 滑块验证的特征 if verify in current_url or captcha in current_url: return captcha # 风险页面的特征 if risk in current_url: return risk # 页面明显异常的特征 if len(page_text) 1000: return empty_page return None检测到异常之后最直接的兜底策略是切换代理 IP清空当前 Cookie等待一段时间后再重新访问。下面是动态切换代理的代码。def switch_proxy(driver, new_proxy): # 动态切换代理无需重启浏览器 driver.execute_cdp_cmd(Network.enable, {}) driver.execute_cdp_cmd(Network.setExtraHTTPHeaders, { headers: { Proxy-Authorization: Basic base64.b64encode( buser:password ).decode(utf-8) } }) driver.execute_cdp_cmd(Network.setCacheDisabled, {cacheDisabled: True})切换完代理之后再访问目标页面如果连续切换三次还是被拦截说明当前账号也被标记了这时候不要硬刚停一段时间再说。爬虫最忌讳的是较劲和反爬系统硬碰硬只会加速 IP 封禁。3.5 完整代码一个可直接改着用的爬虫骨架把前面几个部分串起来我给出一个完整的爬虫骨架。这个骨架覆盖了初始化浏览器、访问搜索页、翻页、解析商品、反爬检测、代理切换的完整流程你可以直接基于它修改。import time import random import re import base64 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def create_driver(proxy_host, proxy_port, proxy_user, proxy_pass): options Options() options.add_argument(--ignore-certificate-errors) options.add_experimental_option(excludeSwitches, [enable-automation]) options.add_experimental_option(useAutomationExtension, False) options.add_argument(--disable-blink-featuresAutomationControlled) options.add_argument(--window-size1920,1080) proxy_url fhttp://{proxy_user}:{proxy_pass}{proxy_host}:{proxy_port} options.add_argument(f--proxy-server{proxy_url}) driver webdriver.Chrome(optionsoptions) driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, {get: () undefined}) }) return driver def check_blocked(driver): current_url driver.current_url if verify in current_url or captcha in current_url: return captcha if risk in current_url: return risk if len(driver.page_source) 1000: return empty_page return None def parse_product(driver): item {} title_selectors [.p-name a em, .p-name a, .p-img img[alt]] for selector in title_selectors: try: el driver.find_element(By.CSS_SELECTOR, selector) item[title] el.get_attribute(title) or el.get_attribute(alt) or el.text if item.get(title): break except Exception: continue price_selectors [.p-price strong, .price, .p-price] for selector in price_selectors: try: price_el WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, selector)) ) text price_el.text.strip() if text: item[price] text break except Exception: continue sku_match re.search(rskuId[:](\d), driver.current_url) if sku_match: item[sku_id] sku_match.group(1) return item def crawl_search_page(driver, keyword, max_pages5): driver.get(fhttps://search.jd.com/Search?keyword{keyword}encutf-8) time.sleep(random.uniform(2, 4)) results [] for page in range(max_pages): block_status check_blocked(driver) if block_status: print(f触发反爬: {block_status}) return results # 滚动加载 for _ in range(3): driver.execute_script(window.scrollBy(0, 500);) time.sleep(random.uniform(0.5, 1.5)) items driver.find_elements(By.CSS_SELECTOR, .gl-item) for item_el in items: try: # 通过执行脚本拿到当前商品卡片的链接 item_url item_el.find_element(By.CSS_SELECTOR, .p-name a).get_attribute(href) if item_url: results.append({page: page 1, url: item_url}) except Exception: continue # 翻页 try: next_btn driver.find_element(By.CSS_SELECTOR, .pagination .next) next_btn.click() time.sleep(random.uniform(2, 4)) except Exception: break return results def main(): # 配置代理 PROXY_HOST proxy-provider.example.com PROXY_PORT 8080 PROXY_USER your_username PROXY_PASS your_password driver create_driver(PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS) try: links crawl_search_page(driver, iPhone 15, max_pages3) print(f采集到 {len(links)} 条商品链接) for link in links[:5]: print(link) finally: driver.quit() if __name__ __main__: main()这个骨架里我只做了搜索页列表的抓取和解析实际项目中你可以在这个基础上扩展遍历商品详情页、解析完整字段、写入数据库或导出 Excel。代码本身不复杂重点是体会整个链路的组织方式。4. 常见问题与排查技巧实录4.1 Selenium 被识别成自动化工具怎么办这是被问到最多的问题也是反爬系统识别爬虫的第一道关口。Selenium 驱动的 Chrome 和正常 Chrome 有一个核心差异window.navigator.webdriver 属性为 true。这是 Chrome 专门给自动化工具留的标记任何基于 WebDriver 协议的工具都会带上。最有效的解决方法是使用 CDP 在页面加载前覆盖这个属性就是我前面代码里写的方式。driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, {get: () undefined}) })这个方案能解决大部分场景但京东这类大厂的反爬系统还会检测更细致的特征比如浏览器是否启用了自动控制相关的扩展、Chrome 是否有特殊启动参数、Canvas 指纹是否异常等。遇到这种情况可以考虑使用 undetected-chromedriver 或者 patch chrome driver它们的原理是修改 chromedriver 的源码从根本上抹除自动化特征。还有一个容易忽视的点不要用默认的 ChromeDriver 端口。反爬系统可以通过扫描本地端口来发现 WebDriver 服务把 WebDriver 端口改成随机值能降低被识别的概率。4.2 代理失效、超时、被京东拉黑的排查思路代理相关的问题占了爬虫运行故障的一大半我把常见的现象和排查方向列成一张表方便你对照检查。现象可能原因排查方向所有请求超时代理 IP 本身不可用或端口被封先用浏览器手动测试代理是否正常部分请求超时代理池中混入了低质量 IP换一家高质量服务商或提高 IP 筛选标准页面能打开但频繁出滑块出口 IP 的请求频率过高降低抓取频率增加随机延迟同一个代理 IP 多次访问被封IP 被京东拉入黑名单切换代理 IP等待一段时间再继续页面打开速度极慢代理延迟过高选择节点更近的代理服务商排查代理问题有一个通用流程先在浏览器里手动配置代理访问一个普通网站确认代理连通性再用同一个代理访问京东看是否能正常打开页面最后才用 Selenium 自动化测试。每一步单独验证能快速定位问题出在哪一层。我在实操中发现很多代理服务商的 IP 在首次访问京东时是正常的但爬了几十个页面后就出滑块了这不是代理质量的问题而是请求频率太高。京东的频控阈值比你想象的低单个 IP 一分钟请求几十次就可能触发风控所以控制节奏比堆 IP 更重要。4.3 滑块验证码的应对与避免滑块验证是京东反爬系统最后的一道硬防线一旦触发程序基本就卡住了。市面上的滑块破解方案无非两种一种是计算缺口坐标模拟人类拖拽轨迹另一种是使用第三方打码平台。但我的经验是一旦频繁出滑块最好的策略不是去破解而是停下来想想为什么触发。滑块出现的核心原因是行为异常包括请求频率过高、IP 信誉度差、浏览器指纹异常等。破解滑块只是治标找到触发的根源才是治本。如果确实需要在滑块出现后恢复我建议使用这种方式先确认滑块触发的原因如果是 IP 问题就换代理如果是同一浏览器实例跑太久就重启浏览器如果是操作太机械化就加入更多随机延迟和鼠标轨迹。多管齐下滑块出现的概率会大幅降低。关于鼠标轨迹可以配合 ActionChains 类模拟让鼠标移动过程更加自然。from selenium.webdriver.common.action_chains import ActionChains action ActionChains(driver) slider driver.find_element(By.CSS_SELECTOR, .slider-btn) action.click_and_hold(slider).perform() action.move_by_offset(200, 0).perform() action.release().perform()注意move_by_offset 是一次性移动真实用户的手势轨迹是有加速度变化的想更逼真就拆成多步移动每步间隔随机毫秒。4.4 高频踩坑速查表最后整理一份我自己踩坑踩出来的速查表每一条都是真金白银换来的经验。元素定位尽量用 CSS 选择器不要用 XPath 里的绝对路径京东改版后绝对路径必挂。每次请求之间必须加随机延迟推荐 2 到 5 秒不要用固定值。不要对同一个关键词连续翻页超过 5 页翻页次数越多越容易触发反爬。使用代理时优先选住宅 IP机房 IP 在京东这种大厂面前信誉度很低。程序异常退出时容易留下浏览器僵尸进程写代码时要确保 finally 里执行 driver.quit()。商品价格字段经常是异步加载的解析前一定要等待元素出现直接定位会拿不到值。抓取到的数据要第一时间存到本地不要攒在内存里最后才写库万一崩了前功尽弃。日志必须打全每条请求的 URL、状态、耗时、当前代理 IP 都要记录排查问题全靠它。Cookie 和 Session 是京东风控的重点关照对象建议每次重启浏览器后先访问首页停留几秒再进入搜索页模拟真实用户的访问路径。不要开多线程跑同一套代理池并发请求会让封号速度呈指数级上升。这些经验看着琐碎但实际运行中每一条都能帮你少踩一个坑。我个人在实际操作中的体会是爬虫这件事七分在细节三分在代码。很多人的代码水平完全够用但就是输在细节上代理选得不对、延迟太规律、元素定位写得太死、日志不完整每个小问题累积起来最终结果就是数据抓不到、号被封。希望你读完这篇文章后不只是复制代码而是把上面这套思路真正理解透。下次遇到别家的反爬策略你也能用自己的方式拆解和应对。
RELATED

相关推荐

CANN AMCT hifloat8_cast 算子解析:FP16/BF16 与 HiFloat8 双向转换的 LUT 查表实现与工程实践

CANN AMCT hifloat8_cast 算子解析:FP16/BF16 与 HiFloat8 双向转换的 LUT 查表实现与工程实践

CANN AMCT hifloat8_cast 算子解析:FP16/BF16 与 HiFloat8 双向转换的 LUT 查表实现与工程实践 【免费下载链接】amct AMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。 项目地址: https://gitcode.com/cann/amct 本文围绕 CANN AMCT 模型压缩工具仓中的…

📅 2026/9/18 20:36:29
微信聊天记录导出完整教程:用 WeChatMsg 免费备份对话并生成年度聊天报告

微信聊天记录导出完整教程:用 WeChatMsg 免费备份对话并生成年度聊天报告

微信聊天记录导出完整教程:用 WeChatMsg 免费备份对话并生成年度聊天报告 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub…

📅 2026/9/18 20:36:29
反射式DLL注入原理与工程实践:PE内存加载全解析

反射式DLL注入原理与工程实践:PE内存加载全解析

1. 这不是“黑科技”,而是一种内存加载的底层工程实践反射式DLL注入(Reflective DLL Injection)这个词,近几年在安全研究、红蓝对抗、软件加固、逆向分析等技术圈里反复被提起,但绝大多数人听到它,第一反应…

📅 2026/9/18 20:31:29
MORE NEWS

更多资讯

📰

Aseprite 像素美术工作流:从角色动画、精灵表到关卡搭建

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

LoRa抗干扰实战:工业复杂电磁环境下的稳定通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Scratch积木渲染性能优化:从DOM瓶颈到GPU加速

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

ESP32+W5500有线以太网:SPI时序、寄存器读写与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

边缘AI芯片SoC资源权衡的12种实战组合

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

EMC测试条件对齐:传导发射与辐射发射复测差异解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬