一、前言在爬虫学习中 requests 做网页请求、 lxmlXPath 做页面解析是最经典的组合。本文以赏金写手接单平台witmall.cn为实战案例从零实现网页数据抓取包含网页请求、编码处理、XPath标签定位、数据清洗全流程适合爬虫入门学习者练手完整代码可直接运行。技术栈Python3 requests re lxml.etree二、环境准备首先安装项目依赖库打开终端执行pip安装pip install requests lxmlrequests 模拟浏览器发送HTTP GET请求获取网页源码lxml 高性能HTML/XML解析库内置XPath语法解析re 正则表达式用于标题字段多余数字清洗三、爬虫思路拆解1. 导入依赖包导入爬虫需要的requests、正则re、lxml解析器2. 构造目标URL目标搜索页链接网站编码为GBK3. 发送GET请求requests.get()获取页面响应手动指定编码 gbk 解决中文乱码4. 构造XPath解析树etree.HTML()将网页文本转为可XPath检索的DOM树5. 表头提取用XPath提取表格表头字段6. 遍历表格行数据跳过表头第一行逐行XPath提取赏金、标题、投标数等7项字段7. 数据清洗正则剔除标题多余数字、空值容错处理8. 打印输出结构化数据四、完整代码实现4.1 导包与请求页面# 1.导入所需第三方库 import requests import re from lxml import etree # 2.目标请求地址 url http://www.witmall.cn/index.php?dosearch_listttxt_search_titletxt_search_title%C9%E7%C7%F8 # 3.发送get请求 resp requests.get(url) # 页面源码charsetgbk手动设置编码解决中文乱码 resp.encoding gbk # 获取网页HTML文本 html resp.text # 打印源码用于调试正式爬取可注释 # print(html)重点说明从页面 meta charsetgbk 可以看出网站编码是GBK若不手动指定 resp.encodinggbk 会出现中文乱码。运行输出4.2 构建XPath解析树提取表头# 将html字符串转为lxml的DOM解析树支持xpath语法检索 tree etree.HTML(html) # XPath提取表格表头table标签classrwdt_listtbody第一行的所有文本 headers tree.xpath(//table[classrwdt_list]/tbody/tr[1]/td/text()) print(表头, headers) # 输出表头[任务赏金, 任务标题, 投标数量, 任务雇主, 任务模式, 任务进度, 剩余时间]XPath语法说明//table[classrwdt_list] 全局查找class等于rwdt_list的table标签/tbody/tr[1] table下tbody的第一行tr表头行/td/text() 提取td标签内的纯文本4.3 循环遍历表格数据逐字段解析# 提取所有数据行tr[1:]切片跳过表头第一行 trs tree.xpath(//table[classrwdt_list]/tbody/tr)[1:] # 循环每一行任务数据 for tr in trs: # 1.任务赏金第1个td下strong标签文本 price tr.xpath(./td[1]/strong/text()) # 三元表达式列表非空取内容并去除首尾空格空则赋值空字符串防索引报错 price price[0].strip() if price else # 2.任务标题第2个td下a标签文本正则清洗多余数字 title tr.xpath(./td[2]/a/text()) title title[0].strip() if title else # 正则替换所有数字为空剔除标题里冗余序号 title re.sub(r\[\d\], , title).strip() # 3.投标数量第3个td直接取文本 num tr.xpath(./td[3]/text()) num num[0].strip() if num else # 4.任务雇主第4个td下a标签文本 boss tr.xpath(./td[4]/a/text()) boss boss[0].strip() if boss else # 5.任务模式第5个td直接取文本 mode tr.xpath(./td[5]/text()) mode mode[0].strip() if mode else # 6.任务进度第6个td直接取文本 progress tr.xpath(./td[6]/text()) progress progress[0].strip() if progress else # 7.剩余时间第7个td下u标签内文本 time tr.xpath(./td[7]/u/text()) time time[0].strip() if time else # 打印单条结构化数据 print(price, title, num, boss, mode, progress, time)4.4 运行输出效果200.00元 写一个未来社区探讨的文案 13 郑苏燕 悬赏任务 进行中 选稿中 600.00元 《社区矫正法》实施一周年主题征文 2 petbrig 悬赏任务 进行中 选稿中 100.00元 社区团购引发文案 16 溢鲜果品 悬赏任务 进行中 选稿中 500元-1000元 关于社区成立居家养老服务中心的请示 2 于猫儿 招标任务 招标中 选稿中 300.00元 社区能人专利想找写手 2 郑苏燕 悬赏任务 已完成 选稿中五、关键技术讲解5.1 空值容错处理xxx[0].strip() if xxx else XPath查询结果永远是列表若页面某个字段为空xpath返回空列表 [] 直接 [0] 索引会报 IndexError 所以用三元判断做容错避免爬虫中断。5.2 正则清洗标题re.sub(r\[\d\],,title)部分标题自带 [1][2] 这类序号正则\[\d\]匹配 [数字] 格式内容全局替换为空实现数据清洗。5.3 相对路径XPath ./td[x]循环中 tr.xpath(./td[1]) 的 . 代表当前tr节点相对路径区别于全局 // 精准锁定当前行的单元格。5.4 网页编码坑点网页meta标注 charsetgbk requests默认自动识别编码容易识别错误手动指定encodinggbk是解决中文乱码最优方案。六、拓展优化方向1. 保存数据到CSV/Excel引入 csv 或 pandas 将抓取数据落地本地文件import csv # 初始化写入器循环内writerow([price,title...])2. 分页爬取分析URL分页参数循环page实现全页数据抓取3. 添加请求头headers模拟浏览器UA防止网站反爬拦截headers{User-Agent:Mozilla/5.0 Chrome/120.0} resprequests.get(url,headersheaders)4. 异常捕获 try except 捕获请求超时、解析异常增强爬虫健壮性七、爬虫合规提醒1. 本案例仅用于Python爬虫技术学习禁止批量抓取商用、恶意爬取网站数据2. 爬取前遵守目标网站 robots.txt 协议控制请求频率避免对服务器造成压力。八、总结本案例完整覆盖requests请求XPath解析数据清洗爬虫三大核心能力是爬虫入门标杆实战掌握lxmlXPath定位表格数据的通用写法表格爬虫通用这套逻辑学会编码处理、空值容错、正则清洗三大爬虫高频问题解决方案可基于本项目拓展分页、存文件、反爬绕过等进阶爬虫知识点。