帮分析爬取一个网页信息 cn.investing.com

2017-11-20 22:59:43 +08:00
 yeyu1989
https://cn.investing.com/stock-screener/?sp=country::37|sector::a|industry::a|equityType::a%3Ceq_market_cap;1

如上,应该是用了很多 js,现在直接用 get 的方式,取到的股票记录数是 0
用 post 的方式,{'sp','country::37|sector::a|industry::a|equityType::a%3Ceq_market_cap;1'}作为 data 输入也不行,得到的结果也是记录数是 0

请问应该怎么解析这个网页?思路是什么?

谢谢!
4725 次点击
所在节点    Python
16 条回复
ospider
2017-11-20 23:10:21 +08:00
直接渲染出来页面啊
qwjhb
2017-11-20 23:14:51 +08:00
yeyu1989
2017-11-21 08:17:52 +08:00
@ospider 渲染页面是指啥?
yeyu1989
2017-11-21 08:45:30 +08:00
@qwjhb 恕我刚入门,没有看懂关键点在哪儿。。下一步应该做什么?
xiaobai987
2017-11-21 09:07:11 +08:00
@yeyu1989 用 py 模拟 post 请求啊
raighne
2017-11-21 09:26:05 +08:00
在 console 打$('#resultsTable tr')看看是不是你要的结果
Marsss
2017-11-21 09:27:49 +08:00
1 楼和 2 楼都已经告诉你答案了,而且都是对的。1 楼的意思是直接使用 selenium 等自动化包驱动浏览器访问目标链接,浏览器运行 js 后渲染得到目标数据,具体实现搜索 selenium 相关知识点。

2 楼的意思是分析 http 请求数据,发现目标数据实际是通过 XHR,带参数 POST 访问 https://cn.investing.com/stock-screener/Service/SearchStocks,直接得到数据。具体分析,可 F12 看 network 或者代理抓包。
qwjhb
2017-11-21 09:42:20 +08:00
@yeyu1989 你要的数据并不是在你写的那个网页里 而是载入网页后通过 api 调用获取的 api 的地址就是我上面写的这个 构造个一样的请求就能获得数据了
建议找本爬虫的书看看 别跟视频教程学
yeyu1989
2017-11-21 09:55:47 +08:00
@qwjhb
data={'sp':'country::37|sector::a|industry::a|equityType::a<eq_market_cap;1'}
header=func.randHeader()
s = requests.post('https://cn.investing.com/stock-screener/Service/SearchStocks',params=data,headers=header)
我这么写的,有什么问题吗?还是没有数据...
yeyu1989
2017-11-21 10:04:02 +08:00
@qwjhb
我现在都是照猫画虎,还没有系统学习过。想着边用边学来着
qwjhb
2017-11-21 10:05:47 +08:00
@yeyu1989 所以建议弄本书 快速的翻下其实更省时间
qwjhb
2017-11-21 10:17:13 +08:00
@yeyu1989 然后 data 不是你写的这些 f12 打开看看

request 是这些内容

POST /stock-screener/Service/SearchStocks HTTP/1.1
Host: cn.investing.com
Connection: keep-alive
Content-Length: 909
Accept: application/json, text/javascript, */*; q=0.01
Origin: https://cn.investing.com
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: https://cn.investing.com/stock-screener/?sp=country::37|sector::a|industry::a|equityType::a|exchange::a%3Ceq_market_cap;1
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ja;q=0.6
Cookie: PHPSESSID=tt0b1qp47ancp40619ftigb2t1; geoC=CN; adBlockerNewUserDomains=1511230139; StickySession=id.70178265937.000.cn.investing.com; adbBLk=6; billboardCounter_6=2; nyxDorf=Y2AxYmYuP2JkNWtgZCkxMjZnYj0%2BJzAzMDRlZw%3D%3D
DNT: 1

data 是这些

country[]:37
sector:2,11,7,10,1,4,9,5,8,3,6,12
industry:63,85,82,21,10,86,7,78,36,25,4,28,67,5,71,27,61,90,23,68,34,89,43,50,81,41,56,59,69,9,83,29,52,100,58,95,102,94,60,53,38,87,31,6,16,48,55,74,66,35,65,40,99,42,92,98,39,70,32,45,77,20,54,33,24,72,51,30,64,2,96,8,14,22,26,80,15,37,93,13,46,1,79,44,75,91,49,62,88,12,47,84,57,76,17,97,18,19,3,11,101,73
equityType:ORD,DRC,Preferred,Unit,ClosedEnd,REIT,ELKS,OpenEnd,Right,ParticipationShare,CapitalSecurity,PerpetualCapitalSecurity,GuaranteeCertificate,IGC,Warrant,SeniorNote,Debenture,ETF,ADR,ETC,ETN
exchange[]:54
exchange[]:103
pn:1
order[col]:eq_market_cap
order[dir]:d
yeyu1989
2017-11-21 17:20:45 +08:00
@qwjhb
header={
'Accept':'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding':'gzip, deflate, br',
'Accept-Language':'zh-CN,zh;q=0.9',
'Connection':'keep-alive',
'Content-Length':'909',
'Content-Type':'application/x-www-form-urlencoded',
'Host':'cn.investing.com',
'Origin':'https://cn.investing.com',
'Referer':'https://cn.investing.com/stock-screener/?sp=country::37|sector::a|industry::a|equityType::a|exchange::a%3Ceq_market_cap;1',
'User-Agent':'Opera/8.0 (Macintosh; PPC Mac OS X; U; en)',
'X-Requested-With':'XMLHttpRequest'
}
data={
'country[]':'37',
'sector':'2,11,7,10,1,4,9,5,8,3,6,12',
'industry':'63,85,82,21,10,86,7,78,36,25,4,28,67,5,71,27,61,90,23,68,34,89,43,50,81,41,56,59,69,9,83,29,52,100,58,95,102,94,60,53,38,87,31,6,16,48,55,74,66,35,65,40,99,42,92,98,39,70,32,45,77,20,54,33,24,72,51,30,64,2,96,8,14,22,26,80,15,37,93,13,46,1,79,44,75,91,49,62,88,12,47,84,57,76,17,97,18,19,3,11,101,73',
'equityType':'ORD,DRC,Preferred,Unit,ClosedEnd,REIT,ELKS,OpenEnd,Right,ParticipationShare,CapitalSecurity,PerpetualCapitalSecurity,GuaranteeCertificate,IGC,Warrant,SeniorNote,Debenture,ETF,ADR,ETC,ETN',
'exchange[]':'54',
'exchange[]':'103',
'pn':'1',
'order[col]':'eq_market_cap',
'order[dir]':'d'
}
session = requests.Session()
s = session.post('https://cn.investing.com/stock-screener/Service/SearchStocks',params=data,headers=header)
html = etree.HTML(s.text)

我理解应该是这么写的?但还是得不到想要的结果...
qwjhb
2017-11-21 20:31:27 +08:00
yeyu1989
2017-11-22 09:53:16 +08:00
@ospider @qwjhb @Marsss
非常感谢各位大神,终于可以了。
不过还有个小问题,就是 post 参数里的 pn:1,貌似只能得到第一页的 50 条记录,我试了一下好像只能一页一页的获取,要获取 70 多次。

这种有什么简便的办法吗?
noreason
2017-11-22 10:13:44 +08:00
@yeyu1989 获取 70 多次对程序不是什么大的影响,不过就是不推荐用 selenium,因为它的访问相当于打开一个网页,会等网页全部渲染完才会执行下一步,效率低下.
更推荐模拟 js 请求获取 json 数据的方式

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/408075

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX