如何使用 Python 脚本下载完整的网页?

Posted

技术标签:

【中文标题】如何使用 Python 脚本下载完整的网页?【英文标题】:How to download a full webpage with a Python script? 【发布时间】:2015-09-21 05:14:03 【问题描述】:

目前我有一个脚本只能下载给定页面的html

现在我想下载网页的所有文件,包括HTMLCSSJS图片文件(就像我们使用任何网站的 ctrl-s 一样)。

我当前的代码是:

import urllib
url = "https://en.wikipedia.org/wiki/Python_%28programming_language%29"
urllib.urlretrieve(url, "t3.html")

我访问了很多问题,但他们都只下载HTML

【问题讨论】:

那么您想通过 HTML 中的链接下载它们指向的内容吗?请注意,***页面包含指向其他页面的链接;你想递归地这样做吗? 是的,我想下载主链接中的所有链接以及它们的 css 和 js 文件。 或者告诉我如何只下载一个给定页面的css和js文件 分解问题。将其分解为小步骤,并分别研究每个步骤。您知道如何获取第一页,所以现在研究如何从 HTML 中提取您想要的链接(提示:这称为解析)。 @jonrsharpe 我只知道要下载第一个网页的 HTML,但它的 css 文件没有下载 【参考方案1】:

试试 Python 库 Scrapy。您可以对 Scrapy 进行编程,通过下载网页、扫描、以下链接来递归扫描网站:

用于从网站中提取所需数据的开源协作框架。以一种快速、简单但可扩展的方式。

【讨论】:

谢谢@barny,但你能告诉我它可以使用beautifulSoup lib还是HTTP Requests来实现,因为我对此有所了解。 天哪,我的答案已被修改。阅读 python, err, Python library Scrapy 文档,例如常见问题解答作为它的第一个答案说:Scrapy 提供了一种用于提取数据的内置机制(称为选择器),但您可以轻松地使用 BeautifulSoup(或 lxml)代替。 doc.scrapy.org/en/1.0/faq.html【参考方案2】:

以下实现使您能够获取子 HTML 网站。它可以进一步开发以获得您需要的其他文件。我坐在depth 变量中为您设置要解析的最大子网站。

import urllib2
from BeautifulSoup import *
from urlparse import urljoin


def crawl(pages, depth=None):
    indexed_url = [] # a list for the main and sub-HTML websites in the main website
    for i in range(depth):
        for page in pages:
            if page not in indexed_url:
                indexed_url.append(page)
                try:
                    c = urllib2.urlopen(page)
                except:
                    print "Could not open %s" % page
                    continue
                soup = BeautifulSoup(c.read())
                links = soup('a') #finding all the sub_links
                for link in links:
                    if 'href' in dict(link.attrs):
                        url = urljoin(page, link['href'])
                        if url.find("'") != -1:
                                continue
                        url = url.split('#')[0] 
                        if url[0:4] == 'http':
                                indexed_url.append(url)
        pages = indexed_url
    return indexed_url


pagelist=["https://en.wikipedia.org/wiki/Python_%28programming_language%29"]
urls = crawl(pagelist, depth=2)
print urls

Python3 版本,2019 年。希望这可以为某人节省一些时间:

#!/usr/bin/env python


import urllib.request as urllib2
from bs4 import *
from urllib.parse  import urljoin


def crawl(pages, depth=None):
    indexed_url = [] # a list for the main and sub-HTML websites in the main website
    for i in range(depth):
        for page in pages:
            if page not in indexed_url:
                indexed_url.append(page)
                try:
                    c = urllib2.urlopen(page)
                except:
                    print( "Could not open %s" % page)
                    continue
                soup = BeautifulSoup(c.read())
                links = soup('a') #finding all the sub_links
                for link in links:
                    if 'href' in dict(link.attrs):
                        url = urljoin(page, link['href'])
                        if url.find("'") != -1:
                                continue
                        url = url.split('#')[0] 
                        if url[0:4] == 'http':
                                indexed_url.append(url)
        pages = indexed_url
    return indexed_url


pagelist=["https://en.wikipedia.org/wiki/Python_%28programming_language%29"]
urls = crawl(pagelist, depth=1)
print( urls )

【讨论】:

就像一个魅力,但它没有回答如何用 CSS 和 JS 下载 html 的问题。无论如何谢谢。 没有像@Alexis 写的那样回答问题 这个更简单更好***.com/a/62207356/1207193【参考方案3】:

您可以使用简单的 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。完全像原始网站一样工作。

【讨论】:

仅下载此特定页面some-page.html?它可以根据基本 url 抓取,比如只获取 http://some-site.com/projects/specific-sub-folder/ 下的页面吗?【参考方案4】:

使用 Python 3+ Requests 和其他标准库。

函数savePage 接收requests.Responsepagefilename 保存它的位置。

pagefilename.html保存在当前文件夹中 根据标签scriptlinkimg下载javascriptscssimages,并保存在文件夹pagefilename_files中。 任何异常都打印在sys.stderr 上,返回一个BeautifulSoup 对象。 请求session 必须是全局变量,除非有人在这里为我们编写了更简洁的代码。

您可以根据自己的需要进行调整。


import os, sys
import requests
from urllib.parse import urljoin
from bs4 import BeautifulSoup

def soupfindAllnSave(pagefolder, url, soup, tag2find='img', inner='src'):
    if not os.path.exists(pagefolder): # create only once
        os.mkdir(pagefolder)
    for res in soup.findAll(tag2find):   # images, css, etc..
        try:
            filename = os.path.basename(res[inner])  
            fileurl = urljoin(url, res.get(inner))
            # rename to saved file path
            # res[inner] # may or may not exist 
            filepath = os.path.join(pagefolder, filename)
            res[inner] = os.path.join(os.path.basename(pagefolder), filename)
            if not os.path.isfile(filepath): # was not downloaded
                with open(filepath, 'wb') as file:
                    filebin = session.get(fileurl)
                    file.write(filebin.content)
        except Exception as exc:      
            print(exc, file=sys.stderr)
    return soup

def savePage(response, pagefilename='page'):    
   url = response.url
   soup = BeautifulSoup(response.text)
   pagefolder = pagefilename+'_files' # page contents 
   soup = soupfindAllnSave(pagefolder, url, soup, 'img', inner='src')
   soup = soupfindAllnSave(pagefolder, url, soup, 'link', inner='href')
   soup = soupfindAllnSave(pagefolder, url, soup, 'script', inner='src')    
   with open(pagefilename+'.html', 'w') as file:
      file.write(soup.prettify())
   return soup

示例保存 google 页面及其内容(google_files 文件夹)

session = requests.Session()
#... whatever requests config you need here
response = session.get('https://www.google.com')
savePage(response, 'google')

【讨论】:

以上是关于如何使用 Python 脚本下载完整的网页?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 识别抓取网页中的完整句子

Python+Selenium基础篇之5-第一个完整的自动化测试脚本

我们如何将完整的网页数据下载到电子表格

如何通过自动下载链接使用 Python 访问 PDF 文件?

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

如何在网页中调用python脚本?