получение только заголовка веб-страницы в python

#python #html #beautifulsoup

#python #HTML #beautifulsoup

Вопрос:

У меня более 5000 веб-страниц, и мне нужны названия всех из них. В моем проекте я использую HTML-анализатор BeautifulSoup, подобный этому.

 soup = BeautifulSoup(open(url).read())
soup('title')[0].string
  

Но это занимает много времени. Только для заголовка веб-страницы я читаю весь файл и создаю дерево синтаксического анализа (я думал, что это причина задержки, поправьте меня, если я ошибаюсь).

Есть ли какой-либо другой простой способ сделать это в python.

Комментарии:

1. Вы пробовали lxml.html ? Это быстрее, чем bs

Ответ №1:

Это, безусловно, было бы быстрее, если бы вы просто использовали простое регулярное выражение, BeautifulSoup это довольно медленно. Вы могли бы сделать что-то вроде:

 import re
regex = re.compile('<title>(.*?)</title>', re.IGNORECASE|re.DOTALL)
regex.search(string_to_search).group(1)
  

Комментарии:

1. Вы должны ограничить подстановочный знак .*? и |re.DOTALL , чтобы он . соответствовал новой строке.

2. Не могли бы вы прочитать веб-страницу итеративным способом, останавливаясь, как только заголовок был найден? Кажется, что можно надежно пропустить почти все содержимое любого сайта, когда требуется только заголовок.

Ответ №2:

Для этого всегда можно использовать регулярное выражение, но оно может сломаться, если вы получите плохо отформатированную страницу. Это было бы что-то вроде этого:

 import re
titleRE = re.compile("<title>(. ?)</title>")
title = titleRE.search(s).group(1)
  

Комментарии:

1. О, я не знал, что у скомпилированного регулярного выражения есть search метод. Это удобно, я распространял его повсюду.

Ответ №3:

Вы даже могли бы использовать простые строковые методы:

 html = '<html> lots of crap <title>Title</title> even more crap </html>'
start = html.find('<title>')   7 # Add length of <title> tag
end = html.find('</title>', start)
title = html[start:end]
  

Однако это гарантирует только то, что <title> найдено раньше </title> на странице. Не то чтобы это было в <head> разделе или что-то в этом роде.

Кроме того, вы должны подтвердить свое предположение, что на самом деле это синтаксический анализ BeautifulSoup, который занимает львиную долю времени. (Я предполагаю, что open(url).read() для получения 5000 ресурсов тоже требуется довольно много времени. Это вы не устраните, независимо от того, как вы «разбираете» HTML.)

Комментарии:

1. Не могли бы вы прочитать веб-страницу итеративным способом, останавливаясь, как только заголовок был найден? Кажется, что можно надежно пропустить почти все содержимое любого сайта, когда требуется только заголовок.

Ответ №4:

Попробуйте

 >> hearders = {'headers':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0'}
>>> n = requests.get('http://www.imdb.com/title/tt0108778/', headers=hearders)
>>> al = n.text
>>> al[al.find('<title>')   7 : al.find('</title>')]
u'Friends (TV Series 1994u20132004) - IMDb'