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 1
试试这个
//*[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
我一般都用正则来取
|