Python: сохранить страницу с большим количеством графики в виде файла.html

Я хочу сохранить посещенную страницу на диске в виде файла. Я использую urllib и URLOpener. Я выбираю сайт http://emma-watson.net/. Файл правильно сохраняется в формате.html, но когда я открыл файл, я заметил, что главное изображение сверху, которое содержит закладки для других подстраниц, не отображается, а также некоторые другие элементы (например, POTD). Как правильно сохранить страницу, чтобы вся страница была сохранена на диске?

def saveUrl(url):
        testfile = urllib.URLopener()
        testfile.retrieve(url,"file.html")
...
saveUrl("http://emma-watson.net")

Экран реальной страницы:Экран открытого файла на моем диске:

1 ответ

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

Вы можете сделать это с помощью полноценной библиотеки веб-скребка, такой как scrapy и просто ограничив его до глубины 1 и не включая ничего другого.

Или вы можете сделать это вручную. Выберите ваш любимый HTML-парсер (BeautifulSoup прост в использовании; html.parser встроен в stdlib; Есть десятки других вариантов). Загрузите страницу, затем проанализируйте полученный файл и отсканируйте его img, a, script и т. д. с URL-адресами, затем загрузите эти URL-адреса, и все готово.

Если вы хотите, чтобы все это хранилось в одном файле, существует целый ряд форматов "файла веб-архива", и разные браузеры (и другие инструменты) поддерживают разные. Основная идея большинства из них заключается в том, что вы создаете zip-файл с файлами в определенном макете и с некоторым расширением, например.webarch вместо.zip. Это легко. Но вам также нужно изменить все абсолютные ссылки на относительные, что немного сложнее. Тем не менее, это не так сложно с таким инструментом, как BeautifulSoup или же html.parser или же lxml,


Как примечание, если вы на самом деле не используете UrlOpener во всяком случае, вы делаете жизнь тяжелее для себя без уважительной причины; просто используйте urlopen, Кроме того, как упоминают документы, вы должны использовать urllib2 не urllib; по факту urllib.urlopen устарело с 2.6. И даже если вам действительно нужно использовать явное средство открытия, как говорят документы: "Если вам не нужна поддержка открытия объектов с использованием схем, отличных от http:, ftp: или file:, вы, вероятно, захотите использовать FancyURLopener ".


Вот простой пример (достаточно, чтобы начать, как только вы решите, что делать, а что нет), используя BeautifulSoup:

import os
import urllib2
import urlparse
import bs4

def saveUrl(url):
    page = urllib2.urlopen(url).read()
    with open("file.html", "wb") as f:
        f.write(page)
    soup = bs4.BeautifulSoup(f)
    for img in soup('img'):
        imgurl = img['src']
        imgpath = urlparse.urlparse(imgurl).path
        imgpath = 'file.html_files/' + imgpath
        os.makedirs(os.path.dirname(imgpath))
        img = urllib2.urlopen(imgurl)
        with open(imgpath, "wb") as f:
            f.write(img)

saveUrl("http://emma-watson.net")

Этот код не будет работать, если есть изображения с относительными ссылками. Чтобы справиться с этим, вам нужно позвонить urlparse.urljoin прикрепить базовый URL. И, поскольку базовый URL может быть задан различными способами, если вы хотите обрабатывать каждую страницу, которую кто-либо когда-либо напишет, вам нужно прочитать документацию и написать соответствующий код. Именно в этот момент вы должны начать смотреть на что-то вроде scrapy, Но, если вы просто хотите работать с несколькими сайтами, просто написать что-то, что работает для этих сайтов, хорошо.


Между тем, если какое-либо из изображений загружается JavaScript по истечении времени загрузки страницы, что является довольно распространенным явлением на современных веб-сайтах, ничего не будет работать, за исключением фактического выполнения этого кода JavaScript. В этот момент вам, вероятно, понадобится инструмент автоматизации браузера, такой как Selenium, или инструмент симулятора браузера, такой как Mechanize+PhantomJS, а не скребок.

Другие вопросы по тегам