【问题标题】:Extracting contents from specific meta tags that are not closed using BeautifulSoup使用 BeautifulSoup 从未关闭的特定元标记中提取内容
【发布时间】:2013-08-10 15:43:50
【问题描述】:

我正在尝试从特定的元标记中解析出内容。这是元标记的结构。前两个用反斜杠关闭,但其余的没有任何结束标记。一旦我得到第三个元标记,<head> 标记之间的全部内容就会返回。我也尝试过soup.findAll(text=re.compile('keyword')),但没有返回任何内容,因为关键字是元标记的属性。

<meta name="csrf-param" content="authenticity_token"/>
<meta name="csrf-token" content="OrpXIt/y9zdAFHWzJXY2EccDi1zNSucxcCOu8+6Mc9c="/>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type'>
<meta content='en_US' http-equiv='Content-Language'>
<meta content='c2y_K2CiLmGeet7GUQc9e3RVGp_gCOxUC4IdJg_RBVo' name='google-site-    verification'>
<meta content='initial-scale=1.0,maximum-scale=1.0,width=device-width' name='viewport'>
<meta content='notranslate' name='google'>
<meta content="Learn about Uber's product, founders, investors and team. Everyone's Private Driver - Request a car from any mobile phone—text message, iPhone and Android apps. Within minutes, a professional driver in a sleek black car will arrive curbside. Automatically charged to your credit card on file, tip included." name='description'>

代码如下:

import csv
import re
import sys
from bs4 import BeautifulSoup
from urllib.request import Request, urlopen

req3 = Request("https://angel.co/uber", headers={'User-Agent': 'Mozilla/5.0')
page3 = urlopen(req3).read()
soup3 = BeautifulSoup(page3)

## This returns the entire web page since the META tags are not closed
desc = soup3.findAll(attrs={"name":"description"}) 

【问题讨论】:

  • 那么你希望得到什么输出?
  • 我想要具有 name="description" 的元标记的内容

标签: python beautifulsoup


【解决方案1】:

编辑: 根据@Albert Chen 的建议,添加了区分大小写的正则表达式。

Python 3 编辑:

from bs4 import BeautifulSoup
import re
import urllib.request

page3 = urllib.request.urlopen("https://angel.co/uber").read()
soup3 = BeautifulSoup(page3)

desc = soup3.findAll(attrs={"name": re.compile(r"description", re.I)}) 
print(desc[0]['content'])

虽然我不确定它是否适用于每个页面:

from bs4 import BeautifulSoup
import re
import urllib

page3 = urllib.urlopen("https://angel.co/uber").read()
soup3 = BeautifulSoup(page3)

desc = soup3.findAll(attrs={"name": re.compile(r"description", re.I)}) 
print(desc[0]['content'].encode('utf-8'))

产量:

Learn about Uber's product, founders, investors and team. Everyone's Private Dri
ver - Request a car from any mobile phoneΓÇötext message, iPhone and Android app
s. Within minutes, a professional driver in a sleek black car will arrive curbsi
de. Automatically charged to your credit card on file, tip included.

【讨论】:

  • 我试过这个 - 我在 desc 上收到语句 print desc[0]['content'].encode('utf-8') 的语法错误......如果我弄清楚为什么我会在这里发帖.. 这是因为 print 语句没有包含在 () 中 - 所以, print (desc[0]['content'].encode('utf-8'))... 我我正在使用 python 3.4.1,不更新答案,因为不确定是否特定于版本
  • 是的,抱歉,这是针对 python2.7 的
【解决方案2】:

我认为这里使用正则表达式应该更好: 示例:

resp = requests.get('url')
soup = BeautifulSoup(resp.text)
desc = soup.find_all(attrs={"name": re.compile(r'Description', re.I)})

【讨论】:

    【解决方案3】:

    根据 ingo 的建议,您可以使用不那么严格的解析器,例如 html5。

    soup3 = BeautifulSoup(page3, 'html5lib')
    

    但请确保系统上有python-html5lib 解析器可用。

    【讨论】:

      【解决方案4】:

      尝试(基于this 博文)

      from bs4 import BeautifulSoup
      ...
      desc = ""
      for meta in soup.findAll("meta"):
          metaname = meta.get('name', '').lower()
          metaprop = meta.get('property', '').lower()
          if 'description' == metaname or metaprop.find("description")>0:
              desc = meta['content'].strip()
      

      针对以下变体进行了测试:

      • &lt;meta name="description" content="blah blah" /&gt; (Example)
      • &lt;meta id="MetaDescription" name="DESCRIPTION" content="blah blah" /&gt; (Example)
      • &lt;meta property="og:description" content="blah blah" /&gt; (Example)

      使用 BeautifulSoup 版本 4.4.1

      【讨论】:

        【解决方案5】:
        soup3 = BeautifulSoup(page3, 'html5lib')
        

        xhtml 要求元标记正确关闭,html5 不需要。 html5lib 解析器更“宽松”。

        【讨论】:

          【解决方案6】:

          描述区分大小写。因此,我们需要同时查找“描述”和“描述”。

          案例 1:Flipkart.com 中的“描述”

          案例 2:Snapdeal.com 中的“描述”

          from bs4 import BeautifulSoup
          import requests
          
          url= 'https://www.flipkart.com'
          page3= requests.get(url)
          soup3= BeautifulSoup(page3.text)
          desc= soup3.find(attrs={'name':'Description'})
          if desc == None:
              desc= soup3.find(attrs={'name':'description'})
          try:
              print desc['content']
          except Exception as e:
              print '%s (%s)' % (e.message, type(e))
          

          【讨论】:

          • 如果两者都存在,如果大写为None,可能想要合并两个结果而不是只搜索小写。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-23
          • 2011-08-25
          • 1970-01-01
          • 1970-01-01
          • 2016-08-14
          • 1970-01-01
          相关资源
          最近更新 更多