Python 如何从HTML中获取特定表
我们有几家公司的10-k表格。我们想从HTML中获取收益表(第6项)。公司的形式结构发生了变化 例如Python 如何从HTML中获取特定表,python,html,web-scraping,Python,Html,Web Scraping,我们有几家公司的10-k表格。我们想从HTML中获取收益表(第6项)。公司的形式结构发生了变化 例如 url1= 'https://www.sec.gov/Archives/edgar/data/794367/000079436719000038/m-0202201910xk.htm' url2='https://www.sec.gov/Archives/edgar/data/885639/000156459019009005/kss-10k_20190202.htm' 我们需要得到第6项合
url1= 'https://www.sec.gov/Archives/edgar/data/794367/000079436719000038/m-0202201910xk.htm'
url2='https://www.sec.gov/Archives/edgar/data/885639/000156459019009005/kss-10k_20190202.htm'
我们需要得到第6项合并财务数据中的表格
我们尝试的一种方法是基于对项目6的字符串搜索,获取从项目6到项目7的所有文本,然后获取如下表格:
doc10K=requests.get(url2)
st6=doc10K.text.lower().find(“第6项”)
end6=doc10K.text.lower().find(“第7项”)
#获取项目6的文本并删除货币符号
item6=doc10K.text[st6:end6]。替换(“$”,“”)
Tsoup=bs.beautifulsou(第6项“lxml”)
#从响应中提取所有表
html\u tables=Tsoup.find\u all('table'))
这种方法并不适用于所有形式。例如,对于KSS,我们无法找到字符串“Item6”。理想的输出是第6项中给出的表格。字符串
第6项
似乎包含空格或不间断空格
请尝试以下代码:
import requests
from bs4 import BeautifulSoup
url1= 'https://www.sec.gov/Archives/edgar/data/794367/000079436719000038/m-0202201910xk.htm'
url2='https://www.sec.gov/Archives/edgar/data/885639/000156459019009005/kss-10k_20190202.htm'
doc10K = requests.get(url2)
st6 = doc10K.text.lower().find("item 6")
# found "item 6"? if not search search with underscore
if st6 == -1:
st6 = doc10K.text.lower().find("item_6")
end6 = doc10K.text.lower().find("item 7")
item6 = doc10K.text[st6:end6].replace('$','')
soup = BeautifulSoup(item6, 'lxml')
html_tables = soup.find_all('table')
彼得苏黎世是对的,但标记没有完全定位
# You can try this, too. The start parameter can be a list, just match any one of the above
doc10K = requests.get(url2)
from simplified_scrapy.simplified_doc import SimplifiedDoc
doc = SimplifiedDoc(doc10K.text)
start = doc.html.rfind('Selected Consolidated Financial Data')
if start<0:
start = doc.html.rfind('Selected Financial Data')
tables = doc.getElementsByTag('table',start=start,end=['Item 7','Item 7'])
for table in tables:
trs = table.trs
for tr in trs:
tds = tr.tds
for td in tds:
print(td.text)
# print(td.unescape()) #Replace HTML entity
#你也可以试试这个。start参数可以是一个列表,只需匹配上面的任意一个即可
doc10K=请求.get(url2)
从simplified_scrapy.simplified_doc导入SimplifiedDoc
doc=SimplifiedDoc(doc10K.text)
start=doc.html.rfind('选定的合并财务数据')
如果使用bs4 4.7.1+启动,则可以使用:contains和:has为基于html的表指定适当的匹配模式。您可以使用css或语法来匹配下面显示的两种模式中的任何一种
import requests
from bs4 import BeautifulSoup as bs
import pandas as pd
urls = ['https://www.sec.gov/Archives/edgar/data/794367/000079436719000038/m-0202201910xk.htm','https://www.sec.gov/Archives/edgar/data/885639/000156459019009005/kss-10k_20190202.htm']
with requests.Session() as s:
for url in urls:
r = s.get(url)
soup = bs(r.content, 'lxml')
table = pd.read_html(str(soup.select_one('table:contains("Item 6") ~ div:has(table) table, p:contains("Selected Consolidated Financial Data") ~ div:has(table) table')))[0]
table.dropna(axis = 0, how = 'all',inplace= True)
table.dropna(axis = 1, how = 'all',inplace= True)
table.fillna(' ', inplace=True)
table.rename(columns= table.iloc[0], inplace = True) #set headers same as row 1
table.drop(table.index[0:2], inplace = True) #lose row 1
table.reset_index(drop=True, inplace = True) #re-index
print(table)
如果你的问题解决了,将其中一个答案标记为已接受。在这一点上,它不会得到表格中的部分,因为内容表格中也有“第6项”。如果内容表存在,我们需要忽略它。我们需要将输出作为一个表,由@qharr完成,这取决于它失败的原因。章节标题和表格似乎没有固定的模式。我的方法是,您至少可以扩展css,或者为标题、标题与表格之间的关系添加其他模式。虽然这对这两种模式很有效,但不能推广到其他URL,例如,您能用“选择一个”来解释这一部分吗,这将有助于修复和推广select_one返回在()中传递的css模式的第一个匹配项。该模式是为匹配您的表而编写的。我使用Or语法指定了两个模式,因此两个模式都是匹配的。这是因为不能对两个URL使用相同的模式,因为title和table之间的关系不同,并且包含title的元素也不同。