xpath爬取过程出现不规则数据的解决方法

在Python中使用XPath爬取boss直聘济南职位信息时,碰到列表元素溢出问题,主要是由于HTML代码中公司规模信息存在不规则。通过异常处理和类型转换方法,可以成功处理这种不规则数据,避免列表索引错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在今天使用xpath库爬取boss直聘济南在找职位的信息时,遇到了一个获取列表元素溢出的情况,具体是什么样的问题,我下面贴图来看一下。
1
大家注意观察这两个职位信息,几乎信息都是规则分布的,但在公司规模信息那里却出现了不规则现象,当然这些不规则也会体现在html代码中。
2
3
大家可以看到,html代码块中的不规则现象不利于我们对信息的提取,如果我们采用下面的方法硬获取,就会报出列表溢出的错误。

size = item.xpath('div[@class="info-company"]/div/p/text()')[2]

因为在缺少一个信息的p标签内不会有位置为[2]的信息,所以系统会报错。
所以我在这里用了一个异常处理来解决这个问题,解决方法如下。

try:
	size = item.xpath('div[@class="info-company"]/div/p/text()')[2]
	size1 = ''.join(size).strip().replace('\n', '')
except:
	size = item.xpath('div[@class="info-company"]/div/p/text()')[1]
	size1 = ''.join(size).strip().replace('\n', '')

这里为什么用了一个size1,是因为xpath返回的结果是列表类型的,我们把它转换成字符串类型易于处理,并且通过strip和replace方法来清理信息的空格和换行。
下面附上爬取boss直聘济南地区招聘信息的完整代码。

__author__ = "Hopes Li"

# 爬取boss直聘全济南招聘信息
# 职位,公司,地点,薪金,规模,经验

# 导入所需库
import requests
from requests.exceptions import RequestException
from bs4 import BeautifulSoup
from lxml import etree


# 获取网页源代码
def get_one_page(url):
    try:
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) '
                                 + 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3510.2 Safari/537.36'}
        response = requests.get(url, headers=headers)
        response.encoding = 'utf-8'
        html = response.text
        soup = BeautifulSoup(html, 'lxml')
        result = soup.prettify()
        xhtml = etree.HTML(result)
        return xhtml
    except RequestException:
        print("Error")


# 主函数解析写入
def main(urls):
    xhtml = get_one_page(urls)
    info = xhtml.xpath('//div[@class="job-primary"]')
    with open(r'C:\Users\Administrator\Desktop\PythonPycharm\爬虫\Xpath库\Boss.csv', 'a', encoding='utf-8') as f:
        for item in info:
            position = item.xpath('div[@class="info-primary"]/h3/a/div[@class="job-title"]/text()')
            position1 = ''.join(position).strip().replace('\n', '')
            salary = item.xpath('div[@class="info-primary"]/h3/a/span[@class="red"]/text()')
            salary1 = ''.join(salary).strip().replace('\n', '')
            address = item.xpath('div[@class="info-primary"]/p/text()')[0]
            address1 = ''.join(address).strip().replace('\n', '')
            experience = item.xpath('div[@class="info-primary"]/p/text()')[1]
            experience1 = ''.join(experience).strip().replace('\n', '')
            company = item.xpath('div[@class="info-company"]/div/h3/a/text()')
            company1 = ''.join(company).strip().replace('\n', '')
            try:
                size = item.xpath('div[@class="info-company"]/div/p/text()')[2]
                size1 = ''.join(size).strip().replace('\n', '')
            except:
                size = item.xpath('div[@class="info-company"]/div/p/text()')[1]
                size1 = ''.join(size).strip().replace('\n', '')

            f.write('{},{},{},{},{},{}\n'.format(position1, salary1, address1, company1, size1, experience1))


# 执行
if __name__ == "__main__":
    for i in range(1, 10):
        urls = 'https://www.zhipin.com/c101120100/h_101120100/?page=' + str(i)
        main(urls)

<think>嗯,用户之前问过网络爬虫写代码时的注意事项,现在又具体问到了使用XPath时的注意事项。看来他们对爬虫技术有一定了解,但可能在实践中遇到了具体问题,比如XPath解析准确或者效率低下。需要先回顾之前给出的建议,确保这次的回答在结构上一致,同时深入XPath特有的问题。 首先,用户的需求是了解使用XPath时的注意事项。需要涵盖XPath语法、定位策略、性能优化、动态内容处理、反爬虫机制应对、容错处理、编码问题以及维护性等方面。之前的回答分了七个部分,这次可能也需要类似的条理,但具体针对XPath。 合法性方面之前已经提到,这可能需要重复,但可能需要提醒遵守网站规则,尤其是在解析数据要侵犯隐私或版权。然后重点放在XPath的正确使用上,比如路径编写、处理动态属性、命名空间等。 用户可能遇到的问题包括XPath表达式稳定,比如网站结构变化导致定位失效,或者处理AJAX加载的内容。这时候需要建议使用相对路径和属性匹配,以及结合Selenium处理动态内容。此外,性能方面,XPath可能比CSS选择器慢,所以需要注意优化表达式,避免过于复杂的查询。 另外,反爬虫方面,使用XPath时可能需要注意请求频率,配合代理和请求头设置,这部分在之前的回答中提到过,这可能需要关联一下。容错处理也很重要,比如在解析时检查元素是否存在,避免因为节点缺失导致程序崩溃。 还要考虑编码问题,同网页可能有同的编码方式,确保正确解析文本内容。维护性方面,建议将XPath表达式集中管理,方便后续修改。最后,可能用户没有明确说,但潜在需求是希望爬虫稳定高效,所以需要强调测试和监控的重要性。 需要检查是否有遗漏点,比如XPath的函数使用,如text()、contains()等,以及处理绝对路径和相对路径的区别。还有浏览器的开发者工具可能会自动生成绝对路径,但实际应用中相对路径更可靠。此外,XPath在处理大型文档时的性能问题,可能需要避免使用//开头,而是指定更具体的路径。 总结下来,回答的结构应该包括语法准确性、定位策略、性能优化、动态内容处理、反爬措施、容错机制、编码处理、维护性建议,以及测试监控。每个部分给出具体的例子和代码片段,帮助用户理解如何实际操作。同时保持与之前的建议一致,比如合法性、请求频率等,但重点放在XPath特有的问题上。</think>在使用XPath进行网页数据爬取时,需特别注意以下核心要点,按实施顺序分步说明: --- ### 一、XPath语法准确性 1. **路径表达式校验** - 通过浏览器开发者工具(F12)的`Console`验证XPath有效性 ```javascript $x('//div[@class="product"]/a/text()') // 实时测试表达式匹配结果 ``` 2. **避免绝对路径依赖** - 优先使用相对路径`//`代替绝对路径`/html/body/...` ```xpath //*[@id="content"]/div[contains(@class,'item')] // 脆弱路径 → 优化为 → //div[starts-with(@class,'item-')]/h2 // 动态匹配 ``` --- ### 二、节点定位策略 1. **多重属性组合定位** ```xpath //input[@name="email" and @type="text"] // 精确匹配 ``` 2. **动态属性处理** - 对类名拼接或随机属性使用`contains()`/`starts-with()` ```xpath //div[contains(@class, "card-")] // 匹配类名包含"card-"的元素 ``` 3. **命名空间处理** - 对SVG或XML文档声明命名空间 ```python from lxml import etree ns = {'svg': 'http://www.w3.org/2000/svg'} tree.xpath('//svg:path/@d', namespaces=ns) ``` --- ### 三、性能优化 1. **减少`//`全局搜索** - 限定搜索范围提升效率 ```xpath //body//div → 优化为 → /html/body/div // 减少扫描范围 ``` 2. **轴选择优化** - 避免低效的`following-sibling`/`preceding`轴 ```xpath //div[following-sibling::span] → 优化为 → //div[../span] ``` 3. **优先使用`@class`而非`text()`** - 文本内容易变,类名稳定性更高 ```xpath //a[text()='详情'] → 优化为 → //a[@class='detail-btn'] ``` --- ### 四、动态内容应对 1. **AJAX加载检测** - 通过XPath检测加载状态元素 ```xpath //div[@id="loading" and @style="display: none;"] ``` 2. **结合Selenium使用** ```python from selenium.webdriver import Chrome driver = Chrome() element = driver.find_element_by_xpath('//div[@data-ajax="true"]') ajax_content = element.get_attribute('innerHTML') ``` --- ### 五、反爬对抗方案 1. **XPath指纹混淆** - 定期更换定位策略防止特征识别 ```xpath 周一使用://div[@class="product-list"]/ul/li 周二更换://section[contains(@id,'prod')]//li ``` 2. **动态元素过滤** - 排除干扰项 ```xpath //div[not(contains(@class, 'advert'))]/p // 过滤广告内容 ``` --- ### 六、容错处理 1. **空防御机制** ```python price = tree.xpath('//span[@class="price"]/text()') if price: price = price[0].strip() else: log.warning("价格元素缺失") ``` 2. **多版本页面兼容** ```xpath (//h1[@id="title"] | //div[@class="title"])[1] // 适配新旧版本 ``` --- ### 七、编码处理 1. **特殊字符转义** ```xpath //button[text()="Don't Stop"] // 正确处理单引号 → 改写为 → //button[text()="Don't Stop"] // 处理HTML实体 ``` --- ### 八、维护性建议 1. **XPath集中管理** ```python # xpath_config.py PRODUCT = { 'title': '//h1[@itemprop="name"]/text()', 'price': '//meta[@itemprop="price"]/@content' } ``` 2. **版本控制标注** ```xpath //div[data-version="2023"]//img // 标注网站改版特征 ``` --- ### 最佳实践示例 ```python from lxml import html def parse_product(page): tree = html.fromstring(page) data = { 'name': tree.xpath('normalize-space(//h1[contains(@class,"title")])'), 'sku': tree.xpath('//div[@data-testid="sku"]/@data-value'), 'images': tree.xpath('//picture/source[contains(@srcset,"webp")]/@srcset') } # 多属性容错 price = tree.xpath('(//span[@class="price"]|//meta[@property="price"])[1]/text()') return {k: v[0] if v else None for k, v in data.items()} ``` --- **重点提示**: - 使用`normalize-space()`处理含换行符的文本 - 优先选择`data-*`属性等稳定性高的标识 - 定期使用`lxml`的`ElementTree`验证XPath有效性 - 对高频访问页面进行XPath缓存(TTL 1小时)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洪博hopes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值