2016-11-09 2 views
2

Я пытаюсь получить содержимое метатега. Проблема в том, что BS4 не может правильно анализировать тег на некоторых сайтах, где тег не закрыт, как и должно быть. С тегами в качестве примера ниже, выход моей функции включает в себя множество беспорядков, включая другие теги, такие как скрипты, ссылки и т. Д. Я считаю, что браузер автоматически закрывает метатег где-то в конце головы, и это поведение сбивает BS4.Скребок неблокированных мета-тегов с BS4

Мой код работает с этим:

<meta name="description" content="content" /> 

и не работает с:

<meta name="description" content="content"> 

Вот код моей функции BS4:

from bs4 import BeautifulSoup 

html = BeautifulSoup(open('/path/file.html'), 'html.parser') 
desc = html.find(attrs={'name':'description'}) 

print(desc) 

Любой способ заставить его работать с этими незакрытыми метатегами?

ответ

1

html5lib or lxml parser бы справиться с этой проблемой правильно:

In [1]: from bs4 import BeautifulSoup 
    ...: 
    ...: data = """ 
    ...: <html> 
    ...:  <head> 
    ...:   <meta name="description" content="content"> 
    ...:   <script> 
    ...:    var i = 0; 
    ...:   </script> 
    ...:  </head> 
    ...:  <body> 
    ...:   <div id="content">content</div> 
    ...:  </body> 
    ...: </html>""" 
    ...: 

In [2]: BeautifulSoup(data, 'html.parser').find(attrs={'name': 'description'}) 
Out[2]: <meta content="content" name="description">\n<script>\n   var i = 0;\n  </script>\n</meta> 

In [3]: BeautifulSoup(data, 'html5lib').find(attrs={'name': 'description'}) 
Out[3]: <meta content="content" name="description"/> 

In [4]: BeautifulSoup(data, 'lxml').find(attrs={'name': 'description'}) 
Out[4]: <meta content="content" name="description"/> 
+0

Спасибо. Оба парсера работают правильно. –

0

Имея получить что-то новое и надеюсь, что это может дать вам некоторую помощь, я думаю, что каждый раз, когда BeautifulSoup найти элемент без соответствующего конечного тега, то он будет продолжать поиск следующий и следующий элемент до его конца родительского тега tag.Maybe вы до сих пор не поняли мою мысль, и тут я сделал небольшой демо:

hello.html 
<!DOCTYPE html> 
    <html lang="en"> 
    <meta name="description" content="content"> 
    <head> 
     <meta charset="UTF-8"> 
     <title>Title</title> 
    </head> 
    <div> 
    <p class="title"><b>The Dormouse's story</b> 

    <p class="story">Once upon a time there were three little sisters; and their names were 
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, 
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and 
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; 
    and they lived at the bottom of a well.</p> 
    </p></div> 
    </body> 
    </html> 

и работать, как вы делали раньше и найти результат ниже:

<meta content="content" name="description"> 
<head> 
<meta charset="utf-8"> 
<title>Title</title> 
</meta></head> 
<body> 
... 
</div></body> 
</meta> 

ok! BeautifulSoup автоматически генерирует метатег конца и позиция которого после тега </body>, но все еще не может видеть тег родительского конца meta </html>, поэтому я имею в виду, что конечный тег должен отражать то же положение, что и его начальный тег. Но я до сих пор не могу убедить себя такое мнение, так что я сделать тест, удалить <p class='title'> закрывающий тег так есть только один </p> тег в <div>...</div>, но после запуска

c = soup.find_all('p', attrs={'class':'title'}) print(c[0])

есть два </p> теги в результате. Так что это правда, как я сказал ранее.

Смежные вопросы