Извлечение содержимого из определенных метатегов, которые не закрыты с помощью BeautifulSoup
Я пытаюсь разобрать контент из определенных мета-тегов. Вот структура метатегов. Первые два закрыты обратной косой чертой, но остальные не имеют закрывающих тегов. Как только я получу 3-й мета-тег, все содержимое между <head>
теги будут возвращены. Я также пробовал soup.findAll(text=re.compile('keyword'))
но это ничего не возвращать, поскольку слово является атрибутом тега meta.
<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"})
6 ответов
редактировать: Добавлено регулярное выражение для чувствительности к регистру, как предложено @Albert Chen.
хотя я не уверен, что он будет работать для каждой страницы:
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.
описание чувствительно к регистру.Итак, нам нужно искать как "описание", так и "описание".
Case1: 'описание' в Flipkart.com
Case2: 'описание' в 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))
soup3 = BeautifulSoup(page3, 'html5lib')
xhtml требует, чтобы метатег был правильно закрыт, html5-нет. Парсер html5lib более "доступные".
попробуйте (на основе этой запись в блоге)
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()
протестировано против следующих вариантов:
-
<meta name="description" content="blah blah" />
(пример) -
<meta id="MetaDescription" name="DESCRIPTION" content="blah blah" />
(пример) -
<meta property="og:description" content="blah blah" />
(пример)
используется версия BeautifulSoup 4.4.1
Я думаю, что здесь использование regexp должно быть лучше: пример:
resp = requests.get('url')
soup = BeautifulSoup(resp.text)
desc = soup.find_all(attrs={"name": re.compile(r'Description', re.I)})
как предложил ingo, вы можете использовать менее строгий парсер, такой как html5.
soup3 = BeautifulSoup(page3, 'html5lib')
но обязательно имейте python-html5lib
парсер доступен в системе.