鱼C论坛

 找回密码
 立即注册
查看: 2061|回复: 10

关于xpath爬取数据的问题

[复制链接]
发表于 2023-5-20 15:18:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
import requests
from lxml import etree
def geturl():
    url = "https://www.zbj.com/search/service/?kw=saas&r=1"
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36 Edg/103.0.1264.37"
    }
    html = requests.get(url=url,headers=head)
    html.encoding = 'utf-8'
    return html
def get_data(html):
    tree = etree.HTML(html.text)
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]  根div的xpath
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div[2]/div/div[3]/div[2]/a/text()            标题的xpath
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div[1]/div/div[3]/div[1]/span/text()               价格的xpath
   
    #问题一:下面这两个xpath打印不出数据
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div[1]/div/div[3]/div[4]/div[2]/div/span[2]/text()  销量的xpath
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div[1]/div/div[3]/div[4]/div[3]/div/span[2]/text()  好评的xpath
    all_div = tree.xpath(r'//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]')

    #问题二:
    #思路是使用for循环遍历出每一个div,在此基础上爬取每一个div的信息
    #title的xpath路劲修改为./div/div[3]/div[2]/a/text()没有数据,应该怎么修改
    for div in all_div:
        title = div.xpath(r'./div[1]/div/div[3]/div[2]/a/text()')
        print(title)
        score = div.xpath(r'./div[1]/div/div[3]/div[4]/div[1]/span[1]/span/text()')
        print(score)
        price = div.xpath(r'./div[1]/div/div[3]/div[1]/span/text()')
        print(price)
        sales = div.xpath('./div[1]/div/div[3]/div[4]/div[2]/div/span[1]/text()') #空列表
        print(sales)
        comment = div.xpath(r'./div[1]/div/div[3]/div[4]/div[3]/div/span[1]/text()') #空列表
        print(comment)
if __name__ == "__main__":
    data = geturl()
    get_data(data)


问题已在注释中说明
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-20 15:18:59 | 显示全部楼层
问题一:销量和好评的xpath打印不出数据的问题,可能是因为对应的元素没有加载出来,可以尝试使用Selenium等工具模拟浏览器行为,等待元素加载完成后再进行爬取。

问题二:title的xpath路径修改为./div/div[3]/div[2]/a/text()没有数据的问题,可能是因为相对路径不正确,可以尝试使用绝对路径或者重新检查相对路径是否正确。另外,也可以尝试使用contains()函数等方法来定位元素。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-20 15:19:29 | 显示全部楼层
问题一可能是由于xpath选择器中路径有误导致无法正确选取对应的数据。建议再次检查这两个xpath的路径是否正确。

问题二中,title的xpath路径应该为./div[1]/div[2]/a/text()。sales和comment的xpath返回的是空列表,可能是因为这些数据是通过前端异步加载得到的,而requests只能获取静态页面的内容,无法获取到异步加载的内容。可以考虑使用selenium等工具实现模拟浏览器行为,以获得完整的页面内容。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-20 15:20:29 | 显示全部楼层
动态渲染
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-20 15:41:20 | 显示全部楼层
问题一可能是因为相应的xpath路径不正确导致。可以使用浏览器的开发者工具检查页面中的元素路径是否与代码中的路径相同,或者尝试重新编写正确的xpath路径。

问题二中title的xpath路径应该修改为 ./div[1]/div/div[3]/div[2]/a/text(),即增加一个 div[1] 来表示在当前div下的第一个子div中查找。Sales和Comment的xpath路径也存在问题,应该修改为 ./div[1]/div/div[3]/div[4]/div[2]/span[2]/text() 和 ./div[1]/div/div[3]/div[4]/div[3]/span[2]/text(),即把 div/span 改成 div/span[2]。

修正后的代码如下:
import requests
from lxml import etree

def geturl():
    url = "https://www.zbj.com/search/service/?kw=saas&r=1"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36 Edg/103.0.1264.37"
    }
    html = requests.get(url=url, headers=headers)
    html.encoding = 'utf-8'
    return html

def get_data(html):
    tree = etree.HTML(html.text)
    all_div = tree.xpath(r'//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]')
    for div in all_div:
        title = div.xpath(r'./div[1]/div/div[3]/div[2]/a/text()')
        print(title)
        score = div.xpath(r'./div[1]/div/div[3]/div[4]/div[1]/span[1]/span/text()')
        print(score)
        price = div.xpath(r'./div[1]/div/div[3]/div[1]/span/text()')
        print(price)
        sales = div.xpath(r'./div[1]/div/div[3]/div[4]/div[2]/span[2]/text()')
        print(sales)
        comment = div.xpath(r'./div[1]/div/div[3]/div[4]/div[3]/span[2]/text()')
        print(comment)

if __name__ == "__main__":
    data = geturl()
    get_data(data)
请注意,页面结构可能随时发生变化,所以需要定期检查代码并根据页面的实际情况进行调整。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-20 16:05:30 | 显示全部楼层
给你改了一下:
import requests
from lxml import etree
def geturl():
    url = "https://www.zbj.com/search/service/?kw=saas&r=1"
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36 Edg/103.0.1264.37"
    }
    html = requests.get(url=url,headers=head)
    html.encoding = 'utf-8'
    return html
def get_data(html):
    tree = etree.HTML(html.text)
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]  根div的xpath
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div[2]/div/div[3]/div[2]/a/text()            标题的xpath
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div[1]/div/div[3]/div[1]/span/text()               价格的xpath
   
    #问题一:下面这两个xpath打印不出数据
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div[1]/div/div[3]/div[4]/div[2]/div/span[2]/text()  销量的xpath
    #//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div[1]/div/div[3]/div[4]/div[3]/div/span[2]/text()  好评的xpath
    all_div = tree.xpath(r'//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div')
    #问题二:
    #思路是使用for循环遍历出每一个div,在此基础上爬取每一个div的信息
    #title的xpath路劲修改为./div/div[3]/div[2]/a/text()没有数据,应该怎么修改
    for div in all_div:
        title = div.xpath(r'./div/div[3]/div[2]/a/text()')
        if not title:
            continue
        print(title)
        score = div.xpath(r'./div/div[3]/div[4]/div[1]/span[1]/span/text()')
        print(score)
        price = div.xpath(r'./div/div[3]/div[1]/span/text()')
        print(price)
        sales = div.xpath('./div/div[3]/div[4]/div[2]/span/div/span[2]/text()') #空列表
        print(sales)
        comment = div.xpath(r'./div/div[3]/div[4]/div[3]/span/div/span[2]/text()') #空列表
        print(comment)
if __name__ == "__main__":
    data = geturl()
    get_data(data)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-20 19:25:33 | 显示全部楼层
isdkz 发表于 2023-5-20 16:05
给你改了一下:

当老六是吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-20 19:43:29 | 显示全部楼层

chatgpt没解决问题自己上手怎么了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-20 19:55:00 | 显示全部楼层
isdkz 发表于 2023-5-20 19:43
chatgpt没解决问题自己上手怎么了

没啥没啥
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-20 20:01:12 | 显示全部楼层
isdkz 发表于 2023-5-20 16:05
给你改了一下:

你这个continue是有东西的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-21 00:16:21 | 显示全部楼层
Tihool 发表于 2023-5-20 20:01
你这个continue是有东西的

那给个最佳鼓励一下呗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-27 11:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表