如何使用BeautifulSoup刮表,因为我无法选择表id属性?

时间:2018-04-03 13:01:04

标签: python html beautifulsoup

我是关于HTML和网页抓取的新手。我一直试图从以下链接中删除表格元素:

https://www.hkex.com.hk/Mutual-Market/Stock-Connect/Statistics/Hong-Kong-and-Mainland-Market-Highlights?sc_lang=en#select3=0&select2=2&select1=28

我想要做的是提取诸如“总营业额”,“总市值”等元素。在我检查时,所有这些元素都在<div class="table-container fixed-freeze-tb-parent" id="Tbl__0">

当我创建BeautifulSoup对象并使用

检索文本文件时,让我感到困惑的是什么
turn180329 = requests.get('https://www.hkex.com.hk/Mutual-Market/Stock-Connect/Statistics/Hong-Kong-and-Mainland-Market-Highlights?sc_lang=en#select3=0&select2=2&select1=28')
turnsoup = bs4.BeautifulSoup(turn180329.text,'lxml')`

`file180329 = open('180329.txt','wb')
for char in turn180329.iter_content(1000000):
    file180329.write(char)
file180329.close()

我可以选择div[class="table-container fixed-freeze-tb-parent"]返回div元素,但在使用

选择id="tbl__0"时未返回任何内容

turn_table = turnsoup.find_all('#tbl__0.table-container fixed-freeze-tb-parent')

提取任何所需的表元素。

百万赞赏并感谢任何可以帮助我的人!!!

3 个答案:

答案 0 :(得分:1)

这是因为当您执行请求时,表中的数据不在html源中。您可以使用浏览器的developers tools并检查网站的请求。在这种情况下,我可以检测到网站提出了将数据提供给网址的请求:https://www.hkex.com.hk/eng/csm/ws/Highlightsearch.asmx/GetData?LangCode=en&TDD=29&TMM=3&TYYYY=2018&_=1522759817885

以json格式返回表的数据。

答案 1 :(得分:1)

就像@Juan Javier Santos Ochoa所说,浏览器实际上发送了另一个URL,服务器使用JSON数据进行响应。这是代码部分,以补充他的答案。

可以修改此网址中的日期部分(TDD=29TMM=3TYYYY=2018)以获取不同日期的结果:

url = 'https://www.hkex.com.hk/eng/csm/ws/Highlightsearch.asmx/GetData?LangCode=en&TDD=29&TMM=3&TYYYY=2018'

感谢@Keyur Potdar指出不需要发送标题。

这是发送请求并获取JSON的行:

r = requests.get(url)
d = r.json()

而且,结果如下:

# Turnover (Mil. shares) - Main Board, GEM
>>> print(d['data'][9]['td'][1])
['232,780', '1,769']

修改

  • 您可以使用JSON Formatter之类的在线服务来了解JSON对象的结构。

答案 2 :(得分:0)

该网站似乎是动态的,即当浏览器打开时,前端脚本会使用后端的值更新DOM。要从动态网站中删除,您需要使用浏览器操作工具,例如selenium

from selenium import webdriver
d = webdriver.Chrome()
import re
from bs4 import BeautifulSoup as soup
d.get('https://www.hkex.com.hk/Mutual-Market/Stock-Connect/Statistics/Hong-Kong-and-Mainland-Market-Highlights?sc_lang=en#select3=0&select2=2&select1=28')
new_data = [[b.text for b in i.find_all('td')] for i in soup(d.page_source, 'lxml').find_all('tr')][2:-2]

输出:

[[u'No. of listed companies', u'1,827', u'352', u'1,406', u'51', u'2,096', u'49'], [u'No. of listed H shares', u'230', u'24', u'n.a.', u'n.a.', u'n.a.', u'n.a.'], [u'No. of listed red-chips stocks', u'158', u'6', u'n.a.', u'n.a.', u'n.a.', u'n.a.'], [u'Total no. of listed securities', u'13,527', u'353', u'n.a.', u'n.a.', u'n.a.', u'n.a.'], [u'Total market capitalisation(Bil. dollars)', u'HKD 34,139', u'HKD 264', u'RMB 32,376', u'RMB 91', u'RMB 23,008', u'RMB 74'], [u'Total negotiable capitalisation (Bil. dollars)', u'n.a.', u'n.a.', u'RMB 27,500', u'RMB 91', u'RMB 16,580', u'RMB 73'], [u'Average P/E ratio (Times)', u'12.42', u'42.23', u'17.72', u'21.42', u'32.89', u'11.06'], [u'Total turnover (Mil. shares)', u'232,780', u'1,769', u'17,027', u'22', u'19,244', u'13'], [u'Total turnover (Mil. dollars)', u'HKD 137,287', u'HKD 821', u'RMB 210,972', u'RMB 158', u'RMB 268,838', u'RMB 72'], [u'Total market turnover(Mil. dollars)', u'HKD 138,108', u'RMB 213,189', u'RMB 268,910']]