Красивый суп и в то время как заявление

1

Я пытаюсь найти первые 30 видеороликов TED (название видео и URL), используя следующий BeautifulSoup script:

import urllib2
from BeautifulSoup import BeautifulSoup

total_pages = 3
page_count = 1
count = 1

url = 'http://www.ted.com/talks?page='

while page_count < total_pages:

    page = urllib2.urlopen("%s%d") %(url, page_count)

    soup = BeautifulSoup(page)

    link = soup.findAll(lambda tag: tag.name == 'a' and tag.findParent('dt', 'thumbnail'))

    outfile = open("test.html", "w")

    print >> outfile, """<head>
            <head>
                    <title>TED Talks Index</title>
            </head>

            <body>

            <br><br><center>

            <table cellpadding=15 cellspacing=0 style='border:1px solid #000;'>"""

    print >> outfile, "<tr><th style='border-bottom:2px solid #E16543; border-right:1px solid #000;'><b>###</b></th><th style='border-bottom:2px solid #E16543; border-right:1px solid #000;'>Name</th><th style='border-bottom:2px solid #E16543;'>URL</th></tr>"

    ted_link = 'http://www.ted.com/'

    for anchor in link:
            print >> outfile, "<tr style='border-bottom:1px solid #000;'><td style='border-right:1px solid #000;'>%s</td><td style='border-right:1px solid #000;'>%s</td><td>http://www.ted.com%s</td></tr>" % (count, anchor['title'], anchor['href'])

    count = count + 1

    print >> outfile, """</table>
                    </body>
                    </html>"""

    page_count = page_count + 1

Код выглядит хорошо, минус две вещи:

  • count, похоже, не увеличивается. Он проходит только и находит содержимое первой страницы, то есть: первые десять, а не тридцать, видео. Почему?

  • Этот бит кода дает мне много ошибок. Я не знаю, как еще реализовать то, что я хочу здесь логически (с urlopen ( "% s% d" ):

код:

total_pages = 3
page_count = 1
count = 1

url = 'http://www.ted.com/talks?page='

while page_count < total_pages:

page = urllib2.urlopen("%s%d") %(url, page_count)
  • 0
    Это не решит вашу проблему, но у вас есть два открывающих <head> вместо тегов <html> и <head> : (IE print >> outfile, """<head> должен быть print >> outfile, """<html>
Теги:
beautifulsoup

1 ответ

1
Лучший ответ

Во-первых, упростите цикл и устраните несколько переменных, которые в этом случае будут равны планетарной плите:

for pagenum in xrange(1, 4):  # The 4 is annoying, write it as 3+1 if you like.
  url = "http://www.ted.com/talks?page=%d" % pagenum
  # do stuff with url

Но откройте файл за пределами цикла, а не открывайте его каждую итерацию. Вот почему вы только увидели 10 результатов: разговаривают 11-20 вместо первой десятки, как вы думали. (Это было бы 21-30, за исключением того, что вы зацикливались на page_count < total_pages, который обрабатывал только первые две страницы.)

И соберите все ссылки сразу, а затем напишите вывод потом. Я убрал стиль HTML, который также упрощает работу с кодом; вместо этого используйте CSS, возможно, элемент inline <style> или добавьте его, если хотите.

import urllib2
from cgi import escape  # Important!
from BeautifulSoup import BeautifulSoup

def is_talk_anchor(tag):
  return tag.name == "a" and tag.findParent("dt", "thumbnail")
links = []
for pagenum in xrange(1, 4):
  soup = BeautifulSoup(urllib2.urlopen("http://www.ted.com/talks?page=%d" % pagenum))
  links.extend(soup.findAll(is_talk_anchor))

out = open("test.html", "w")

print >>out, """<html><head><title>TED Talks Index</title></head>
<body>
<table>
<tr><th>#</th><th>Name</th><th>URL</th></tr>"""

for x, a in enumerate(links):
  print >>out, "<tr><td>%d</td><td>%s</td><td>http://www.ted.com%s</td></tr>" % (x + 1, escape(a["title"]), escape(a["href"]))

print >>out, "</table>"

# Or, as an ordered list:
print >>out, "<ol>"
for a in links:
  print >>out, """<li><a href="http://www.ted.com%s">%s</a></li>""" % (escape(a["href"], True), escape(a["title"]))
print >>out, "</ol>"

print >>out, "</body></html>"
  • 0
    Спасибо! Не могли бы вы объяснить "из побега импорта cgi"?
  • 0
    @AdamC .: Если один из URL-адресов или заголовков содержит символ, особенный для HTML, а именно &, <или или "(поскольку я использовал двойные кавычки в одном выводе), escape () будет обрабатывать их, поэтому вы не будете создайте недопустимую разметку. Вы больше не захотите ничего из модуля cgi, но это происходит из-за того, что он находится в stdlib и содержит эту удобную функцию. docs.python.org/library/cgi.html#cgi.escape

Ещё вопросы

Сообщество Overcoder
Наверх
Меню