【问题标题】:parsing meta tag with Beautiful Soup and Python用 Beautiful Soup 和 Python 解析元标记
【发布时间】:2012-11-25 23:11:00
【问题描述】:

我无法使用 Beautiful Soup 3 和 python 2.6 解析 HTML 页面。

HTML 内容是这样的:

content='<div class="egV2_EventReportCardLeftBlockShortWidth">
<span class="egV2_EventReportCardTitle">When</span>
<span class="egV2_EventReportCardBody">
<meta itemprop="startDate" content="2012-11-23T10:00:00.0000000">
<span class='egV2_archivedDateEnded'>STARTS</span>Fri 23 Nov,10:00AM<br/>
<meta itemprop="endDate" content="2012-12-03T18:00:00.0000000">
<span class='egV2_archivedDateEnded'>ENDS</span>Mon 03 Dec,6:00PM</span>
<span class="egV2_EventReportCardBody"></span>
<div class="egV2_div_cal" onclick=" showExportEvent()">
<div class="egV2_div_cal_outerFix">
<div class="egV2_div_cal_InnerAdjust"> Cal </div>
</div></div></div>'

我想将字符串“Fri 23 Nov,10:00AM”从中间取出到一个变量中,用于连接并发送回 PHP 页面。

要阅读此内容,我使用以下代码: (以上内容来自一个 html 页面阅读(http://everguide.com.au/melbourne/event/2012-nov-23/life-with-bird-spring-warehouse-sale/)

import urllib2
req = urllib2.Request(URL)
response = urllib2.urlopen(req)
html = response.read()
from BeautifulSoup import BeautifulSoup
soup = BeautifulSoup(html.decode('utf-8'))
soup.prettify()
import re
for node in soup.findAll(itemprop="name"):
    n = ''.join(node.findAll(text=True)) 
for node in soup.findAll("div", { "class" : "egV2_EventReportCardLeftBlockShortWidth" }):
    d = ''.join(node.findAll(text=True))
print n,"|", d

返回:

[(ssh user)]# python testscrape.py

LIFE with BIRD Spring Warehouse Sale | 
When
<span class="egV2_EventReportCardDateTitle">STARTS</span>
STARTSFri 23 Nov,10:00AMENDSMon 03 Dec,6:00PM
<span class="egV2_EventReportCardDateTitle">ENDS</span>



 Cal 



[(ssh user)]# 

(它包括所有这些换行符等)。

所以你可以在最后看到,我将两个剥离的字符串组合成一个打印输出,中间有一个分隔符,PHP 可以将字符串读回一个,然后将其分开。

问题是 - python 代码可以读取该页面并存储文本,但它包含所有那些让 PHP 应用程序混淆的垃圾和标签等。

我真的只想退货:

Fri 23 Nov,10:00AM

是因为我使用 findAll(text=True) 方法吗?

我怎样才能向下钻取并仅获取该 div 中的文本 - 而不是 span 标签?

任何帮助将不胜感激,谢谢。

瑞克 - 墨尔本。

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    为什么不试试类似的东西

    In [95]: soup = BeautifulSoup(content)
    
    In [96]: soup.find("span", {"class": "egV2_archivedDateEnded"})
    Out[96]: <span class="egV2_archivedDateEnded">STARTS</span>
    
    In [97]: soup.find("span", {"class": "egV2_archivedDateEnded"}).next
    Out[97]: u'STARTS'
    
    In [98]: soup.find("span", {"class": "egV2_archivedDateEnded"}).next.next
    Out[98]: u'Fri 23 Nov,10:00AM'
    

    甚至

    In [99]: soup.find("span", {"class": "egV2_archivedDateEnded"}).nextSibling
    Out[99]: u'Fri 23 Nov,10:00AM'
    

    【讨论】:

    • 太棒了!我什至曾想过使用 Next Sibling!它并不是最容易阅读的文档(BS4)!干杯。
    【解决方案2】:

    如果你只是想提取一个很容易用特定属性识别的单个标签,pyparsing 让这变得非常简单(我会使用它的 ISO8601 时间字符串值的元标签):

    from pyparsing import makeHTMLTags,withAttribute
    
    meta = makeHTMLTags('meta')[0]
    # only want matching <meta> tags if they have the attribute itemprop="startDate"
    meta.setParseAction(withAttribute(itemprop="startDate"))
    
    # scanString is a generator that yields (tokens,startloc,endloc) triples, we just 
    # want the tokens
    firstmatch = next(meta.scanString(content))[0]
    

    现在转换为 datetime 对象,它可以按您喜欢的方式进行格式化、写入数据库、用于计算经过的时间等:

    from datetime import datetime
    dt = datetime.strptime(firstmatch.content[:19], "%Y-%m-%dT%H:%M:%S")
    
    print (firstmatch.content)
    print (dt)
    

    打印:

    2012-11-23T10:00:00.0000000
    2012-11-23 10:00:00
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-27
      • 2015-11-10
      • 2013-10-21
      • 2014-04-21
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多