【问题标题】:Python Web Scraping - html parsingPython Web Scraping - html 解析
【发布时间】:2019-06-03 09:44:34
【问题描述】:

我正在尝试从 nasdaq 网站提取系统状态消息。以下是部分页面源码:

</script>
<h2>System Status Messages</h2>
<div id='divSSTAT'>
<div class="genTable">
<table style="width: 100%">
<colgroup>
<col class="gtcol1"></col>
<col class="gtcol2"></col>
<col class="gtcol3"></col>
</colgroup>
<tr>
<th class="gtcol1" style="width: 10%">Time</th>
<th class="gtcol2" style="width: 25%">Market</th>
<th class="gtcol3">Status</th>
</tr>
<tr class='sstatNone' ><td class="tddateWidth" style="white-space: nowrap;">11:56:46 ET</td><td class="tdmarketwidth">NASDAQ<br>BX<br>Post - Trade<br>PSX<br>NASDAQ Options<br>BX Options<br>PHLX<br>NASDAQ Futures<br>ISE<br>GEMX<br>MRX</td><td valign="top">Systems are operating normally</td></tr>
</table>
</div>
</div>

想要这样的输出:

System Status Messages
11:56:46 Systems are operating normally

这是我提取页面内容的方法:

from urllib.request import urlopen
from bs4 import BeautifulSoup
url = "https://www.nasdaqtrader.com/Trader.aspx?id=MarketSystemStatus"
html = urlopen(url)
soup = BeautifulSoup(html, 'lxml')
soup.find_all(["h2","tr"])

这会产生很多不需要的内容。清理它的最佳方法是什么,尤其是包含实际系统消息的行?现在是这样的……

<tr class='sstatNone' ><td class="tddateWidth" style="white-space: nowrap;">11:56:46 ET</td><td class="tdmarketwidth">NASDAQ<br>BX<br>Post - Trade<br>PSX<br>NASDAQ Options<br>BX Options<br>PHLX<br>NASDAQ Futures<br>ISE<br>GEMX<br>MRX</td><td valign="top">Systems are operating normally</td></tr>

谢谢!

【问题讨论】:

标签: python web-scraping beautifulsoup urllib


【解决方案1】:

你可以遍历td标签

from bs4 import BeautifulSoup as soup
s = soup(content, 'html.parser')
_start, *_, _end = [i.text for i in s.find_all('td')]
results = f'{s.h2.text}\n{_start} {_end}'
print(results)

输出:

System Status Messages
11:56:46 ET Systems are operating normally

如果您不想在输出中包含ET,可以使用re.sub

import re
...
results = f'{s.h2.text}\n{re.sub(" [A-Z]+", "", _start)} {_end}'

输出:

System Status Messages
11:56:46 Systems are operating normally

【讨论】:

  • 这很好用。非常感谢!可能应该是一个单独的线程,但是你知道是否有一个包来重复相同的任务,例如每 10 秒,而不是写一个循环来这样做?
  • @user10144318 很高兴为您提供帮助!
  • 要经常重复它,你可以使用 crontab
  • @user10144318 这在某种程度上取决于。如果你想在控制台中运行程序,一个简单的while 循环和time.sleep 就足够了。但是,如果您希望按特定时间表执行程序,请参阅here
【解决方案2】:

在下面,您可以将 3 个选择器组合拆分为 3 个单独的 select_one('indiv selector combination here') 选择。只是为了兴趣而显示。请注意,较长的选择器和使用量词的选择器在 css 方面的性能稍差。

import requests
from bs4 import BeautifulSoup as bs
url = 'https://www.nasdaqtrader.com/Trader.aspx?id=MarketSystemStatus'
res = requests.get(url)
soup = bs(res.content,'lxml')
print(' '.join([item.text for item in soup.select('#content h2:nth-of-type(1), #divSSTAT .tddateWidth, #divSSTAT td:nth-of-type(3)')]))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    相关资源
    最近更新 更多