import trio
import httpx
from bs4 import BeautifulSoup
import pandas as pd
from functools import partial
async def main(url):
async with httpx.AsyncClient(timeout=None) as client:
r = await client.get(url)
soup = BeautifulSoup(r.text, 'lxml')
tfile = soup.select_one('.file-link:-soup-contains(Table)').a['href']
async with client.stream('GET', tfile) as r:
fname = r.headers.get('content-disposition').split('=')[-1]
async with await trio.open_file(fname, 'wb') as f:
async for chunk in r.aiter_bytes():
await f.write(chunk)
df = await trio.to_thread.run_sync(partial(pd.read_excel, fname, sheet_name=3, engine="pyxlsb"))
print(df)
if __name__ == "__main__":
trio.run(main, 'https://rigcount.bakerhughes.com/na-rig-count')
输出:
Country County Basin DrillFor ... Week RigCount State/Province PublishDate
0 UNITED STATES SABINE Haynesville Gas ... 13 1 LOUISIANA 40634
1 UNITED STATES TERREBONNE Other Oil ... 13 1 LOUISIANA 40634
2 UNITED STATES VERMILION Other Gas ... 13 1 LOUISIANA 40634
3 UNITED STATES VERMILION Other Gas ... 13 1 LOUISIANA 40634
4 UNITED STATES EDDY Permian Oil ... 13 1 NEW MEXICO 40634
... ... ... ... ... ... ... ... ... ...
769390 UNITED STATES KERN Other Oil ... 29 1 CALIFORNIA 44393
769391 UNITED STATES KERN Other Oil ... 29 1 CALIFORNIA 44393
769392 UNITED STATES KERN Other Oil ... 29 1 CALIFORNIA 44393
769393 UNITED STATES KERN Other Oil ... 29 1 CALIFORNIA 44393
769394 UNITED STATES KERN Other Oil ... 29 1 CALIFORNIA 44393
[769395 rows x 13 columns]
>注意:您似乎遇到了 `pyxlsb` 阅读器中的错误。使用索引读取工作表是原因,但使用 `sheet_name='Master Data'` 可以正常工作。
更新:
问题是excel文件有2个隐藏表,第2个表确实有1457行,主数据实际上是第4个表,所以sheet_name=3可以工作
上次更新:
为了关注Python DRY Principle。我注意到我们不需要将文件保存在本地,甚至不需要将文件可视化并存储到内存中,然后将其加载到 pandas。
实际上response的内容本身是存储在内存中的,所以我们可以通过将r.content直接传递给pandas来一次性加载!
使用下面的代码:
import trio
import httpx
from bs4 import BeautifulSoup
import pandas as pd
from functools import partial
async def main(url):
async with httpx.AsyncClient(timeout=None) as client:
r = await client.get(url)
soup = BeautifulSoup(r.text, 'lxml')
tfile = soup.select_one('.file-link:-soup-contains(Table)').a['href']
r = await client.get(tfile)
df = await trio.to_thread.run_sync(partial(pd.read_excel, r.content, sheet_name=3, engine="pyxlsb"))
print(df)
if __name__ == "__main__":
trio.run(main, 'https://rigcount.bakerhughes.com/na-rig-count')