爬虫XPath实战:抓取赏金写手网站任务数据
2026/6/6 8:11:10 网站建设 项目流程

一、前言


在爬虫学习中, requests 做网页请求、 lxml+XPath 做页面解析是最经典的组合。本文以赏金写手接单平台(witmall.cn)为实战案例,从零实现网页数据抓取,包含网页请求、编码处理、XPath标签定位、数据清洗全流程,适合爬虫入门学习者练手,完整代码可直接运行。

技术栈:Python3 + requests + re + lxml.etree

二、环境准备

首先安装项目依赖库,打开终端执行pip安装:

pip install requests lxml

requests :模拟浏览器发送HTTP GET请求,获取网页源码
lxml :高性能HTML/XML解析库,内置XPath语法解析
re :正则表达式,用于标题字段多余数字清洗

三、爬虫思路拆解

1. 导入依赖包:导入爬虫需要的requests、正则re、lxml解析器
2. 构造目标URL:目标搜索页链接,网站编码为GBK
3. 发送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?do=search_list&t=txt_search_title&txt_search_title=%C9%E7%C7%F8" # 3.发送get请求 resp = requests.get(url) # 页面源码charset=gbk,手动设置编码,解决中文乱码 resp.encoding = "gbk" # 获取网页HTML文本 html = resp.text # 打印源码用于调试(正式爬取可注释) # print(html)

重点说明:从页面 <meta charset="gbk"> 可以看出网站编码是GBK,若不手动指定 resp.encoding="gbk" ,会出现中文乱码。

运行输出:

4.2 构建XPath解析树,提取表头

# 将html字符串转为lxml的DOM解析树,支持xpath语法检索 tree = etree.HTML(html) # XPath提取表格表头:table标签class="rwdt_list",tbody第一行的所有文本 headers = tree.xpath('//table[@class="rwdt_list"]/tbody/tr[1]/td/text()') print("表头:", headers) # 输出:表头:['任务赏金', '任务标题', '投标数量', '任务雇主', '任务模式', '任务进度', '剩余时间']

XPath语法说明:

//table[@class="rwdt_list"] :全局查找class等于rwdt_list的table标签
/tbody/tr[1] :table下tbody的第一行tr(表头行)
/td/text() :提取td标签内的纯文本

4.3 循环遍历表格数据,逐字段解析

# 提取所有数据行tr,[1:]切片跳过表头第一行 trs = tree.xpath('//table[@class="rwdt_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标注 charset=gbk ,requests默认自动识别编码容易识别错误,手动指定encoding=gbk是解决中文乱码最优方案。

六、拓展优化方向

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"} resp=requests.get(url,headers=headers)

4. 异常捕获: try except 捕获请求超时、解析异常,增强爬虫健壮性

七、爬虫合规提醒

1. 本案例仅用于Python爬虫技术学习,禁止批量抓取商用、恶意爬取网站数据;
2. 爬取前遵守目标网站 robots.txt 协议,控制请求频率,避免对服务器造成压力。

八、总结

本案例完整覆盖requests请求+XPath解析+数据清洗爬虫三大核心能力,是爬虫入门标杆实战:

掌握lxml+XPath定位表格数据的通用写法,表格爬虫通用这套逻辑;
学会编码处理、空值容错、正则清洗三大爬虫高频问题解决方案;
可基于本项目拓展分页、存文件、反爬绕过等进阶爬虫知识点。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询