http://eid.csrc.gov.cn/fund/disclose/instance_html_view.do?instanceid=11733222 http://eid.csrc.gov.cn/fund/disclose/instance_html_view.do?instanceid=11733213
在上面这两个链接中我想获取对应的基金名称,我在浏览器里面获取到的 full XPath 如下
/html/body/table/tbody/tr/td[2]/table/tbody/tr[1]/td[1]/div/table[1]/tbody/tr[2]/td/div/div/table/tbody/tr[1]/td[2]/p
但是第二个链接中我能顺利获取到值,第一个获取到的内容为空
为了给大佬省事,对应的代码如下
from ast import main from fake_useragent import UserAgent from lxml import etree import requests ua = UserAgent() headers = {"user-agent": ua.random} url1 = "http://eid.csrc.gov.cn/fund/disclose/instance_html_view.do?instanceid=11733222" url2 = "http://eid.csrc.gov.cn/fund/disclose/instance_html_view.do?instanceid=11733213" def get_fund_name(url: str): x = requests.get(url, headers = headers) selector = etree.HTML(x.content) fund_name = selector.xpath('/html/body/table/tbody/tr/td[2]/table/tbody/tr[1]/td[1]/div/table[1]/tbody/tr[2]/td/div/div/table/tbody/tr[1]/td[2]/p/text()') return fund_name print(get_fund_name(url1)) print(get_fund_name(url2))
output 如下
[] ['长信利盈灵活配置混合型证券投资基金']
我仔细对比了这两个网页,实在是找不到原因……
1 dongtingyue 2022-09-14 18:47:23 +08:00 有些 dom 是 js 渲染的 |
![]() | 2 MrVito OP @dongtingyue 你可以看下这个网页,应该是纯静态的 |
4 humbass 2022-09-14 19:03:54 +08:00 2202 年的爬虫应该用 JS 来实现更强大;比如 Puppeteer |
5 tankren 2022-09-14 19:04:17 +08:00 用 try+except 抛个异常看看,为啥要用绝对路径啊,不是不推荐吗 |
![]() | 10 zengxs 2022-09-14 19:26:19 +08:00 ![]() 试试这个 //*[contains(text(), '基金名称')]/../../td[2]/p/text() |
15 humbass 2022-09-14 20:24:26 +08:00 网页是 JS 写的,爬虫当然是 JS 来写解析 DOM 结构也是天然的! Python 是过去式了; ``` const jsdom = require('jsdom') const axios = require('axios') ;(async () => { const url = 'http://eid.csrc.gov.cn/xbrl/REPORT/HTML/2022/FC190100/CN_50470000_009421_FC190100_20220039/CN_50470000_009421_FC190100_20220039.html' const respOnse= await axios.get(url) const result = new jsdom.JSDOM(response.data) const table = result.window.document.querySelector('#tabItem0') const title = table.querySelectorAll('p')[1].textContent console.log('title:', title) })() `` |
![]() | 16 zjuster 2022-09-14 20:44:36 +08:00 如果 Xpath 写的绝对路径太多了,可能要比较一下两个页面(虽然链接一致),但在 Dom 结构可能不一致的情况。 写的宽泛一点试试看。 |
![]() | 19 zengxs 2022-09-14 21:31:48 +08:00 via iPhone @humbass 这个是和底层的 html parser 有关,和语言关系不大,jsdom 用的 html parser 和浏览器的也不一样 |
20 wxf666 2022-09-14 21:32:15 +08:00 |
21 humbass 2022-09-14 21:37:09 +08:00 |
22 wxf666 2022-09-14 21:48:47 +08:00 @humbass xpath 不是 Python 的,只是 lxml 库的一个功能。这个库好像不支持 css 风格的查询 换成 BeautifulSoup 库就支持了:xxx.select('#tabItem0') 另外,我还是觉得 xpath 更方便描述 xml html |
![]() | 23 zengxs 2022-09-14 22:07:56 +08:00 via iPhone @humbass 呃,xpath 和 css selector 只是两种不同的 html 查询方式而已,和语言无关,python 也可以 css selector 查询,js 也可以 xpath 查询 至于哪个更方便这个也不好说,css selector 语法简单是牺牲了很多功能换来的 |
![]() | 25 webcape233 2022-09-15 02:05:22 +08:00 via iPhone 这简单查询观察下写正则可能更快 |
![]() | 26 mscststs 2022-09-15 02:47:57 +08:00 看到 tbody 就要注意了,浏览器会自动在 table 里面自动填充一级 tbody ,这就是为什么你取 Xpath 是一样的,实际上你右键查看源码,就能看出来,第一个链接的 html 没有在源码里面手写 tbody ,而第二个写了。 |
![]() | 27 ADMlN 2022-09-15 05:02:37 +08:00 xpath 改成'/html/body/table/tbody',第一个为空,第二个有值 |
![]() | 28 brucmao 2022-09-15 09:16:19 +08:00 //p[contains(text(),'基金名称')]/../following-sibling::td/p 页面复制的经常不准确,可以试试 xpath 轴 https://developer.mozilla.org/en-US/docs/Web/XPath 另外可以用浏览器插件 SelectorsHub 辅助 |
![]() | 29 JieGaLee 2022-09-15 09:32:27 +08:00 遇到 tbody 就要去源码里确认一下是不是真的有 tbody 。 |
![]() | 30 hidie 2022-09-15 10:00:33 +08:00 不要写 tbody |
31 fbichijing 2022-09-15 17:03:12 +08:00 一个有 tbody 一个没有,所以找不到。 这么深层数的筛选器加上那么多的位置 index ,简直是独木桥中的独木桥啊。 |
![]() | 32 ijustdo 2022-09-15 18:15:09 +08:00 //div[@id="con_one_1"][1]/descendant::table/descendant::tr[1]/td[2]/p/text() |
33 chunhai 2022-09-19 19:36:35 +08:00 我一般都用正则来取 |