鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: 江湖散人

[已解决]数据爬取中xpath的使用问题

[复制链接]
发表于 2021-8-29 14:19:08 | 显示全部楼层
本帖最后由 阿奇_o 于 2021-8-29 14:21 编辑
江湖散人 发表于 2021-8-29 13:49
如何动态加载啊?
用xpath就不好使了吗?


可以这样理解:
第一次requests.get()的发出请求后,就返回了一个HMTL,这个HTML没多少的东西
(比如这里即没有表格部分的数据,常常是固定的布局和导航等,变动的数据常常不在里面),

于是你对响应回来的HTML(response.text)进行xpath查找(或css等其他查找方式)自然就找不到,锅里没骨头,怎么能叫骨头汤呢。

其次,这原始的HTML里还包括一个js脚本,浏览器加载了最初的HTML后,还会加载这个脚本,
从而让页面的HTML发生改变(这里即把表数据加载进来)而地址栏的URL并没有改变,这个过程可以叫做"js渲染"或"动态加载"。
而现在基本上都是用 Ajax技术(说白了就是比一般的js动态加载更快的异步加载方式),所以在爬虫时常叫"Ajax分析"。

根据Ajax分析,我们可以找到一些规律和线索,比如,发现它用的是POST方法,动态请求的地址是.../getPriceData.html, post的数据data或param或files 是xxx...

你自己多搜搜相关关键词吧,我也是现学现卖而已,可不保"这瓜熟吗"。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-29 16:23:57 | 显示全部楼层
阿奇_o 发表于 2021-8-29 14:19
可以这样理解:
第一次requests.get()的发出请求后,就返回了一个HMTL,这个HTML没多少的东西
(比如 ...

还是你厉害啊,能找到这么多东西。
但是我用post后的数据是一个字典,然后是不是可以根据字典的特性来提取数据了,比如说dic["key"] = values
这样就可以把values都取出来,是吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-29 19:27:59 | 显示全部楼层
打开网页,F12,选择Network, Fetch/XHR, 点击第二页换页,找到
http://www.xinfadi.com.cn/getPriceData.html,点击第三页会出来一个新的,看提交的参数就行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-29 19:30:29 | 显示全部楼层
江湖散人 发表于 2021-8-29 13:49
如何动态加载啊?
用xpath就不好使了吗?

当你查看网页源代码时,找不到第一页的蔬菜大白菜,娃娃菜啥的都查找不到,这说明网页不是静态的
但你点击第二页时,你会发现网页url没有发生改变但是网页内容产生了变化,这说明网页不是静态的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-29 19:52:17 | 显示全部楼层
本帖最后由 阿奇_o 于 2021-8-29 19:57 编辑
江湖散人 发表于 2021-8-29 16:23
还是你厉害啊,能找到这么多东西。
但是我用post后的数据是一个字典,然后是不是可以根据字典的特性来提 ...


post()返回的是JSON数据吧,json本身是字符串,长得像字典而已。
import json  
json.loads()很容易就可以把json字符串转为一般的Python字典了,这个转化过程又叫"解析json"
转成了字典,通常又会生成 df=pandas.DataFrame(data)方便做数据分析,或保存df.to_excel(), df.to_sql() 等等。。

不懂的话,直接百度/bing.com/谷歌,解析json是很常见的操作。菜鸟教程网,W3Cschool等网站都很好……

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

使用道具 举报

 楼主| 发表于 2021-8-30 08:21:55 | 显示全部楼层
南归 发表于 2021-8-29 19:30
当你查看网页源代码时,找不到第一页的蔬菜大白菜,娃娃菜啥的都查找不到,这说明网页不是静态的
但你点击 ...

好的,谢谢你啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-30 08:24:09 | 显示全部楼层
阿奇_o 发表于 2021-8-29 19:52
post()返回的是JSON数据吧,json本身是字符串,长得像字典而已。
import json  
json.loads()很容易 ...

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

使用道具 举报

 楼主| 发表于 2021-9-1 13:58:51 | 显示全部楼层
阿奇_o 发表于 2021-8-29 11:56
哈哈,我昨晚查了些资料,原来是requests等库不能"动态加载",只能获取到原始的HTML,而Selenium等则可以动 ...
import requests
from lxml import etree

url = "http://www.xinfadi.com.cn/priceDetail.html"
resp = requests.get(url)
tree = etree.HTML(resp.text)
table = tree.xpath("/html/body/div[2]/div/div/div/div[4]/div[1]/div/table/tbody")[0]
trs = table.xpath("./tr")
print(len(trs))

你好,就这个问题我还有一点不明白,就是table = tree.xpath("/html/body/div[2]/div/div/div/div[4]/div[1]/div/table/tbody")[0]
这里为什么要后边加一个【0】啊?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-1 16:01:30 | 显示全部楼层
江湖散人 发表于 2021-9-1 13:58
你好,就这个问题我还有一点不明白,就是table = tree.xpath("/html/body/div[2]/div/div/div/div[4] ...


这很简单呀,因为它返回的是"列表",你只要看到可以做切片[]操作的,都可以当做 list 看,
虽然具体还有元组那样的"序列",反正一般来说是序列式的对象,都可以切片。
这里可能遇到的问题是,可能找不到而返回的是空列表,当你切片时,就会导致下标报错。
所以要确认,是否列表里面返回的都是正常的Element。是的话,你就可以使用相关的属性和方法。
具体你看官方教程吧https://lxml.de/tutorial.html
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-13 13:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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