Tihool 发表于 2023-5-20 15:18:36

关于xpath爬取数据的问题

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/div/div/div/div/div根div的xpath
    #//*[@id="__layout"]/div/div/div/div/div/div/div/div/div/div/div/a/text()            标题的xpath
    #//*[@id="__layout"]/div/div/div/div/div/div/div/div/div/div/div/span/text()               价格的xpath
   
    #问题一:下面这两个xpath打印不出数据
    #//*[@id="__layout"]/div/div/div/div/div/div/div/div/div/div/div/div/div/span/text()销量的xpath
    #//*[@id="__layout"]/div/div/div/div/div/div/div/div/div/div/div/div/div/span/text()好评的xpath
    all_div = tree.xpath(r'//*[@id="__layout"]/div/div/div/div/div/div/div')

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


问题已在注释中说明

isdkz 发表于 2023-5-20 15:18:59

问题一:销量和好评的xpath打印不出数据的问题,可能是因为对应的元素没有加载出来,可以尝试使用Selenium等工具模拟浏览器行为,等待元素加载完成后再进行爬取。

问题二:title的xpath路径修改为./div/div/div/a/text()没有数据的问题,可能是因为相对路径不正确,可以尝试使用绝对路径或者重新检查相对路径是否正确。另外,也可以尝试使用contains()函数等方法来定位元素。

陶远航 发表于 2023-5-20 15:19:29

问题一可能是由于xpath选择器中路径有误导致无法正确选取对应的数据。建议再次检查这两个xpath的路径是否正确。

问题二中,title的xpath路径应该为./div/div/a/text()。sales和comment的xpath返回的是空列表,可能是因为这些数据是通过前端异步加载得到的,而requests只能获取静态页面的内容,无法获取到异步加载的内容。可以考虑使用selenium等工具实现模拟浏览器行为,以获得完整的页面内容。

歌者文明清理员 发表于 2023-5-20 15:20:29

动态渲染

sfqxx 发表于 2023-5-20 15:41:20

问题一可能是因为相应的xpath路径不正确导致。可以使用浏览器的开发者工具检查页面中的元素路径是否与代码中的路径相同,或者尝试重新编写正确的xpath路径。

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

修正后的代码如下:

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/div/div/div/div/div')
    for div in all_div:
      title = div.xpath(r'./div/div/div/div/a/text()')
      print(title)
      score = div.xpath(r'./div/div/div/div/div/span/span/text()')
      print(score)
      price = div.xpath(r'./div/div/div/div/span/text()')
      print(price)
      sales = div.xpath(r'./div/div/div/div/div/span/text()')
      print(sales)
      comment = div.xpath(r'./div/div/div/div/div/span/text()')
      print(comment)

if __name__ == "__main__":
    data = geturl()
    get_data(data)
请注意,页面结构可能随时发生变化,所以需要定期检查代码并根据页面的实际情况进行调整。

isdkz 发表于 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/div/div/div/div/div根div的xpath
    #//*[@id="__layout"]/div/div/div/div/div/div/div/div/div/div/div/a/text()            标题的xpath
    #//*[@id="__layout"]/div/div/div/div/div/div/div/div/div/div/div/span/text()               价格的xpath
   
    #问题一:下面这两个xpath打印不出数据
    #//*[@id="__layout"]/div/div/div/div/div/div/div/div/div/div/div/div/div/span/text()销量的xpath
    #//*[@id="__layout"]/div/div/div/div/div/div/div/div/div/div/div/div/div/span/text()好评的xpath
    all_div = tree.xpath(r'//*[@id="__layout"]/div/div/div/div/div/div/div/div')
    #问题二:
    #思路是使用for循环遍历出每一个div,在此基础上爬取每一个div的信息
    #title的xpath路劲修改为./div/div/div/a/text()没有数据,应该怎么修改
    for div in all_div:
      title = div.xpath(r'./div/div/div/a/text()')
      if not title:
            continue
      print(title)
      score = div.xpath(r'./div/div/div/div/span/span/text()')
      print(score)
      price = div.xpath(r'./div/div/div/span/text()')
      print(price)
      sales = div.xpath('./div/div/div/div/span/div/span/text()') #空列表
      print(sales)
      comment = div.xpath(r'./div/div/div/div/span/div/span/text()') #空列表
      print(comment)
if __name__ == "__main__":
    data = geturl()
    get_data(data)

sfqxx 发表于 2023-5-20 19:25:33

isdkz 发表于 2023-5-20 16:05
给你改了一下:

当老六是吧{:10_307:}

isdkz 发表于 2023-5-20 19:43:29

sfqxx 发表于 2023-5-20 19:25
当老六是吧

chatgpt没解决问题自己上手怎么了{:5_94:}

sfqxx 发表于 2023-5-20 19:55:00

isdkz 发表于 2023-5-20 19:43
chatgpt没解决问题自己上手怎么了

没啥没啥{:10_260:}

Tihool 发表于 2023-5-20 20:01:12

isdkz 发表于 2023-5-20 16:05
给你改了一下:

你这个continue是有东西的{:10_254:}

isdkz 发表于 2023-5-21 00:16:21

Tihool 发表于 2023-5-20 20:01
你这个continue是有东西的

那给个最佳鼓励一下呗{:5_92:}
页: [1]
查看完整版本: 关于xpath爬取数据的问题