如何使用 Python 保存“完整网页”而不仅仅是基本的 html

Posted

技术标签:

【中文标题】如何使用 Python 保存“完整网页”而不仅仅是基本的 html【英文标题】:How to save "complete webpage" not just basic html using Python 【发布时间】:2013-01-09 02:36:57 【问题描述】:

我正在使用以下代码使用 Python 保存网页:

import urllib
import sys
from bs4 import BeautifulSoup

url = 'http://www.vodafone.de/privat/tarife/red-smartphone-tarife.html'
f = urllib.urlretrieve(url,'test.html')

问题:此代码将 html 保存为基本 html,没有 javascript、图像等。我想将网页保存为完整的(就像我们在浏览器中有选项一样)

更新: 我现在使用以下代码来保存 webapge 的所有 js/images/css 文件,以便它可以保存为完整的网页,但我的输出 html 仍然像基本 html 一样保存:

import pycurl
import StringIO

c = pycurl.Curl()
c.setopt(pycurl.URL, "http://www.vodafone.de/privat/tarife/red-smartphone-tarife.html")

b = StringIO.StringIO()
c.setopt(pycurl.WRITEFUNCTION, b.write)
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.MAXREDIRS, 5)
c.perform()
html = b.getvalue()
#print html
fh = open("file.html", "w")
fh.write(html)
fh.close()

【问题讨论】:

然后你必须编写代码来解析 HTML,获取所有链接的资源,然后像浏览器一样单独下载它们。 用美汤可以吗? 试试Scrapy,一个开源的可移植Python网页抓取框架 如何使用它?我对编程很陌生,我对美丽的汤有一些经验。 类似:Is it possible to get complete source code of a website including css by just providing the URL of website? + Python 【参考方案1】:

尝试使用selenium 模拟您的浏览器。此脚本将弹出网页的save as 对话框。您仍然需要弄清楚如何模拟按 Enter 以开始下载,因为文件对话框超出了 selenium 的范围(您的操作方式也取决于操作系统)。

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

br = webdriver.Firefox()
br.get('http://www.google.com/')

save_me = ActionChains(br).key_down(Keys.CONTROL)\
         .key_down('s').key_up(Keys.CONTROL).key_up('s')
save_me.perform()

另外,我认为遵循 @Amber 的获取链接资源的建议可能更简单,因此是更好的解决方案。不过,我认为使用 selenium 是一个很好的起点,因为 br.page_source 会为您提供整个 dom 以及 javascript 生成的动态内容。

【讨论】:

这段代码给我WindowsError: [Error 2] The system cannot find the file specified错误 @atams -- 你在哪一行得到错误?我试过了,它在我的机器上运行... 我在这一行出现错误:'br = webdriver.Firefox()',是因为我使用的是便携式版本的 firefox? Ctrl+S触发后,你要如何点击“保存”按钮? @geogeogeo @user2262504 只需按回车键即可保存:save_me = ActionChains(driver).key_down(Keys.ENTER).key_up(Keys.ENTER) save_me.perform()【参考方案2】:

您可以使用简单的 python 库 pywebcopy 轻松做到这一点。

对于当前版本:5.0.1

from pywebcopy import save_webpage

url = 'http://some-site.com/some-page.html'
download_folder = '/path/to/downloads/'    

kwargs = 'bypass_robots': True, 'project_name': 'recognisable-name'

save_webpage(url, download_folder, **kwargs)

您的下载文件夹中将包含 html、css、js。完全像原始网站一样工作。

【讨论】:

这个库真的很有用!但是,有没有一种方法可以找到网页的 html 文件并在浏览器中启动它,而无需手动搜索和定位它?我需要下载完整的网页,然后通过 .py 脚本从 html 文件启动页面 从 github 试用版本 6 Beta。它会自动在浏览器中打开 html。 github.com/rajatomar788/pywebcopy/tree/Beta?files=1【参考方案3】:

要让@rajatomar788 上面的脚本运行,我必须先执行以下所有导入:

要运行 pywebcopy,您需要安装以下软件包:

pip install pywebcopy 
pip install pyquery
pip install w3lib
pip install parse 
pip install lxml

之后它出现了一些错误,但我确实得到了包含构成网页的文件的文件夹。

webpage    - INFO     - Starting save_assets Action on url: 'http://www.gatsby.ucl.ac.uk/teaching/courses/ml1-2016.html'
webpage    - Level 100 - Queueing download of <89> asset files.
Exception in thread <Element(LinkTag, file:///++resource++images/favicon2.ico)>:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\pywebcopy\elements.py", line 312, in run
    super(LinkTag, self).run()
  File "C:\ProgramData\Anaconda3\lib\site-packages\pywebcopy\elements.py", line 58, in run
    self.download_file()
  File "C:\ProgramData\Anaconda3\lib\site-packages\pywebcopy\elements.py", line 107, in download_file
    req = SESSION.get(url, stream=True)
  File "C:\ProgramData\Anaconda3\lib\site-packages\pywebcopy\configs.py", line 244, in get
    return super(AccessAwareSession, self).get(url, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\requests\sessions.py", line 546, in get
    return self.request('GET', url, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\requests\sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\requests\sessions.py", line 640, in send
    adapter = self.get_adapter(url=request.url)
  File "C:\ProgramData\Anaconda3\lib\site-packages\requests\sessions.py", line 731, in get_adapter
    raise InvalidSchema("No connection adapters were found for '%s'" % url)
requests.exceptions.InvalidSchema: No connection adapters were found for 'file:///++resource++images/favicon2.ico'

webpage    - INFO     - Starting save_html Action on url: 'http://www.gatsby.ucl.ac.uk/teaching/courses/ml1-2016.html'

【讨论】:

以上是关于如何使用 Python 保存“完整网页”而不仅仅是基本的 html的主要内容,如果未能解决你的问题,请参考以下文章

在 VSCode 中,如何在 python 文件上应用单引号,而不仅仅是打字稿,更漂亮?

如何保存所有绑定的数据,而不仅仅是可见页面的数据

MFC C++:如何将某个文件实际保存到系统中,而不仅仅是打开另存为对话框

Spring boot 的 Postman Post 请求保存了整个 JSON 正文,而不仅仅是字段值。我该如何解决?

如何指定属性必须是(比如说)整数列表,而不仅仅是列表?

使用更多 cookie 而不仅仅是会话哈希进行身份验证的原因是啥?