1. 程式人生 > >Python抓取HTML網頁並以PDF儲存

Python抓取HTML網頁並以PDF儲存

一、前言

今天介紹將HTML網頁抓取下來,然後以PDF儲存,廢話不多說直接進入教程。

二、準備工作

from PyPDF2 import PdfFileMerger
merger = PdfFileMerger()
input1 = open("hql_1_20.pdf", "rb")
input2 = open("hql_21_40.pdf", "rb")
merger.append(input1)
merger.append(input2)
# Write to an output PDF document
output = open("hql_all.pdf", "wb")
merger.write(output)
  1. requests、beautifulsoup 是爬蟲兩大神器,reuqests 用於網路請求,beautifusoup 用於操作 html 資料。有了這兩把梭子,幹起活來利索。scrapy 這樣的爬蟲框架我們就不用了,這樣的小程式派上它有點殺雞用牛刀的意思。此外,既然是把 html 檔案轉為 pdf,那麼也要有相應的庫支援, wkhtmltopdf 就是一個非常的工具,它可以用適用於多平臺的 html 到 pdf 的轉換,pdfkit 是 wkhtmltopdf 的Python封裝包。首先安裝好下面的依賴包
    pip install requests
    pip install beautifulsoup4
    pip install pdfkit
  2. 安裝 wkhtmltopdf

    Windows平臺直接在 http://wkhtmltopdf.org/downloads.html 下載穩定版的 wkhtmltopdf 進行安裝,安裝完成之後把該程式的執行路徑加入到系統環境 $PATH 變數中,否則 pdfkit 找不到 wkhtmltopdf 就出現錯誤 “No wkhtmltopdf executable found”。Ubuntu 和 CentOS 可以直接用命令列進行安裝

    $ sudo apt-get install wkhtmltopdf  # ubuntu
    $ sudo yum intsall wkhtmltopdf      # centos

三、資料準備

1.獲取每篇文章的url

def get_url_list():
    """
    獲取所有URL目錄列表
    :return:
    """
    response = requests.get("http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000")
    soup = BeautifulSoup(response.content, "html.parser")
    
    #menu_tag = soup.find_all(class_="uk-nav uk-nav-side")[1]
    menu_tag = soup.find_all(class_="x-wiki-index-item")[1]
    urls = []
    for li in menu_tag.find_all("li"):
        url = "http://www.liaoxuefeng.com" + li.a.get('href')
        urls.append(url)
    return urls

2.通過文章url用模板儲存每篇文章的HTML檔案

html模板:

html_template = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
{content}
</body>
</html>

"""

進行儲存:

def parse_url_to_html(url, name):
    """
    解析URL,返回HTML內容
    :param url:解析的url
    :param name: 儲存的html檔名
    :return: html
    """
    try:
        response = requests.get(url)
        soup = BeautifulSoup(response.content, 'html.parser')
        # 正文
        body = soup.find_all(class_="x-wiki-content")[0]
        # 標題
        title = soup.find('h4').get_text()

        # 標題加入到正文的最前面,居中顯示
        center_tag = soup.new_tag("center")
        title_tag = soup.new_tag('h1')
        title_tag.string = title
        center_tag.insert(1, title_tag)
        body.insert(1, center_tag)
        html = str(body)
        # body中的img標籤的src相對路徑的改成絕對路徑
        pattern = "(<img .*?src=\")(.*?)(\")"

        def func(m):
            if not m.group(3).startswith("http"):
                rtn = m.group(1) + "http://www.liaoxuefeng.com" + m.group(2) + m.group(3)
                return rtn
            else:
                return m.group(1)+m.group(2)+m.group(3)
        html = re.compile(pattern).sub(func, html)
        html = html_template.format(content=html)
        html = html.encode("utf-8")
        with open(name, 'wb') as f:
            f.write(html)
        return name

    except Exception as e:

        logging.error("解析錯誤", exc_info=True)

3.把html轉換成pdf

def save_pdf(htmls, file_name):
    """
    把所有html檔案儲存到pdf檔案
    :param htmls:  html檔案列表
    :param file_name: pdf檔名
    :return:
    """
    options = {
        'page-size': 'Letter',
        'margin-top': '0.75in',
        'margin-right': '0.75in',
        'margin-bottom': '0.75in',
        'margin-left': '0.75in',
        'encoding': "UTF-8",
        'custom-header': [
            ('Accept-Encoding', 'gzip')
        ],
        'cookie': [
            ('cookie-name1', 'cookie-value1'),
            ('cookie-name2', 'cookie-value2'),
        ],
        'outline-depth': 10,
    }
    pdfkit.from_file(htmls, file_name, options=options)

4.把轉換好的單個PDF合併為一個PDF

    merger = PdfFileMerger()
    for pdf in pdfs:
       merger.append(open(pdf,'rb'))
       print u"合併完成第"+str(i)+'個pdf'+pdf

完整原始碼:

# coding=utf-8
import os
import re
import time
import logging
import pdfkit
import requests
from bs4 import BeautifulSoup
from PyPDF2 import PdfFileMerger

html_template = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
{content}
</body>
</html>

"""


def parse_url_to_html(url, name):
    """
    解析URL,返回HTML內容
    :param url:解析的url
    :param name: 儲存的html檔名
    :return: html
    """
    try:
        response = requests.get(url)
        soup = BeautifulSoup(response.content, 'html.parser')
        # 正文
        body = soup.find_all(class_="x-wiki-content")[0]
        # 標題
        title = soup.find('h4').get_text()

        # 標題加入到正文的最前面,居中顯示
        center_tag = soup.new_tag("center")
        title_tag = soup.new_tag('h1')
        title_tag.string = title
        center_tag.insert(1, title_tag)
        body.insert(1, center_tag)
        html = str(body)
        # body中的img標籤的src相對路徑的改成絕對路徑
        pattern = "(<img .*?src=\")(.*?)(\")"

        def func(m):
            if not m.group(3).startswith("http"):
                rtn = m.group(1) + "http://www.liaoxuefeng.com" + m.group(2) + m.group(3)
                return rtn
            else:
                return m.group(1)+m.group(2)+m.group(3)
        html = re.compile(pattern).sub(func, html)
        html = html_template.format(content=html)
        html = html.encode("utf-8")
        with open(name, 'wb') as f:
            f.write(html)
        return name

    except Exception as e:

        logging.error("解析錯誤", exc_info=True)


def get_url_list():
    """
    獲取所有URL目錄列表
    :return:
    """
    response = requests.get("http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000")
    soup = BeautifulSoup(response.content, "html.parser")
    
    #menu_tag = soup.find_all(class_="uk-nav uk-nav-side")[1]
    menu_tag = soup.find_all(class_="x-wiki-index-item")[1]
    urls = []
    for li in menu_tag.find_all("li"):
        url = "http://www.liaoxuefeng.com" + li.a.get('href')
        urls.append(url)
    return urls


def save_pdf(htmls, file_name):
    """
    把所有html檔案儲存到pdf檔案
    :param htmls:  html檔案列表
    :param file_name: pdf檔名
    :return:
    """
    options = {
        'page-size': 'Letter',
        'margin-top': '0.75in',
        'margin-right': '0.75in',
        'margin-bottom': '0.75in',
        'margin-left': '0.75in',
        'encoding': "UTF-8",
        'custom-header': [
            ('Accept-Encoding', 'gzip')
        ],
        'cookie': [
            ('cookie-name1', 'cookie-value1'),
            ('cookie-name2', 'cookie-value2'),
        ],
        'outline-depth': 10,
    }
    pdfkit.from_file(htmls, file_name, options=options)


def main():
    start = time.time()
    file_name = u"liaoxuefeng_Python3_tutorial"
    urls = get_url_list()
    for index, url in enumerate(urls):
      parse_url_to_html(url, str(index) + ".html")
    htmls =[]
    pdfs =[]
    for i in range(0,124):
        htmls.append(str(i)+'.html')
        pdfs.append(file_name+str(i)+'.pdf')

        save_pdf(str(i)+'.html', file_name+str(i)+'.pdf')

        print u"轉換完成第"+str(i)+'個html'

    merger = PdfFileMerger()
    for pdf in pdfs:
       merger.append(open(pdf,'rb'))
       print u"合併完成第"+str(i)+'個pdf'+pdf

    output = open(u"廖雪峰Python_all.pdf", "wb")
    merger.write(output)

    print u"輸出PDF成功!"

    for html in htmls:
        os.remove(html)
        print u"刪除臨時檔案"+html

    for pdf in pdfs:
        os.remove(pdf)
        print u"刪除臨時檔案"+pdf

    total_time = time.time() - start
    print(u"總共耗時:%f 秒" % total_time)


if __name__ == '__main__':
    main()

相關推薦

PythonHTML網頁PDF儲存

一、前言 今天介紹將HTML網頁抓取下來,然後以PDF儲存,廢話不多說直接進入教程。 二、準備工作 from PyPDF2 import PdfFileMerger merger = PdfFileMerger() input1 = open("hql_1_

【新手】用pythonhtml程式碼儲存到txt檔案

import urllib r=urllib.urlopen(“http://www.w3school.com.cn/html5/index.asp“)//獲取html程式碼 f=f.open(“\Users\Desktop\123.txt”,”w”) f

Python網路爬蟲動態網頁將資料存入資料庫MYSQL

簡述 以下的程式碼是使用python實現的網路爬蟲,抓取動態網頁http://hb.qq.com/baoliao/。此網頁中的最新、精華下面的內容是由JavaScript動態生成的。審查網頁元素與網頁原始碼是不同。 本人對於Python學習建立了一個小小的學習圈子,為各位提供了

Python網頁儲存PDF

1、開發環境搭建 (1)Python2.7.13的安裝:參考《廖雪峰老師的網站》 (2)Python包管理器pip的安裝:參考《pip安裝文件說明》 因為基於版本2.7.13,因為2.7.9以上已經自帶pip,所以不需要單獨安裝,但是需要我們更新。上面的說

python資訊文章儲存htmlpdf格式

一、需求 研究生學長讓我把一個植物表型資訊系列文章的一系列文章爬下來儲存為pdf或者html格式。 首頁網址: https://mp.weixin.qq.com/s?__biz=MzI0Mjg5ODI1Ng==&mid=2247486022&idx=1&sn=

無比強大!Pythoncssmoban站點的模版下載

jea blank file timeout 全局 -- 文件的 pre target Python實現抓取http://www.cssmoban.com/cssthemes站點的模版並下載 實現代碼 # -*- coding: utf-8 -*- im

Python使用lxml模塊和Requests模塊HTML頁面的教程

有時 oms 世界 tel 4.0 取出 itl imp syntax Web抓取Web站點使用HTML描述,這意味著每個web頁面是一個結構化的文檔。有時從中 獲取數據同時保持它的結構是有用的。web站點不總是以容易處理的格式, 如 csv 或者 json 提供它們的數據

Python 網頁gb2312亂碼問題

發現 file read earch () spa .com pycharm close python 爬取學校所有人四六級成績時發現爬出網頁中文亂碼 遂google 得到一解決方案 # -*- coding:utf8 -*- import urllib2

《一出好戲》講述人性,使用Python貓眼近10萬條評論分析,一起揭秘“這出好戲”到底如何?

generate pro hand stk 同時 readlines 看電影 就是 msh 黃渤首次導演的電影《一出好戲》自8月10日在全國上映,至今已有10天,其主演陣容強大,相信許多觀眾也都是沖著明星們去的。目前《一出好戲》在貓眼上已經獲得近60萬個評價,評分為8.2

記錄一次python網頁下載視訊

最近看了電影狂暴巨獸,連結是那種不固定的http連結,有可能隨時就打不開了,然後想下載下來留著,但是網頁不提供下載,所以就自己抓取了相關視訊,然後下載。廢話不多說,直接上乾貨。 用fiddle抓取主要的視訊。下圖就是抓取時候產生的相關資訊。 逐條進行分析,然後找到電影的包的地址。 http

使用pythonhtml網頁轉成pdf檔案

我們看到一些比較寫的比較好文章或者部落格的時候,想儲存下來到本地當一個pdf檔案,當做自己的知識儲備,以後即使這個部落格或者文章的連線不存在了,或者被刪掉,咱們自己也還有。 當然咱們作為一個coder,這樣的事情肯定不能手動儲存下來然後再轉成pdf存起來對不對,有失咱們碼農的身份,當然要自動化的來實現了~

pythonjenkins slave總數、online數、offline數寫道mysql展現

python抓取jenkins slave總數、online數、offline數寫道mysql並展現到grafana: mysql -u root -p'xxxx' create database jenkins default character set utf8;create table sla

福利!NodeJs爬網路教程生成PDF檔案,阮一峰JavaScript教程和ES6教程為例(附原始碼和PDF檔案)

前言 你想一夜暴富嗎?你想一夜成名嗎?你想開蘭博基尼泡妞嗎?你想拿鈔票點菸嗎?你想成為世界主宰嗎?那麼,趕緊往下看吧,雖然它不能達成前面所說的任 何一個夢想,但是,你將獲得: 通過命令列將某網站的內容轉成PDF檔案 通過NodeJS爬蟲將某網路教程(例如阮一峰的JavaScript教程和ES6教

python網頁資料處理後視覺化

抓取文章的連結,訪問量儲存到本地 1 #coding=utf-8 2 import requests as req 3 import re 4 import urllib 5 from bs4 import BeautifulSoup 6 import sys 7 import code

Python電視劇《天盛長歌》豆瓣短評,製作成詞雲。

最近在看《天盛長歌》,才看了30多集,感覺裡邊的劇情還是很有深度,每個反派都是智商線上,劇情也是環環相扣,以至於每個鏡頭給了哪些特寫我都要細細斟酌一番。不過可能劇情是根據小說改編,所以部分劇情有些老套,而且因為節奏有點慢,劇情過多,光是大皇子領盒飯就用了20集。目前來說不喜歡

python爬蟲爬非同步載入網頁資訊(python網頁中無法通過網頁標籤屬性的內容)

1.問題描述 最近由於學習內容的要求,需要從網頁上抓取一些資料來做分析報告,在看了python爬蟲的一些基礎知識之後就直接上手去網站上爬資料了。作為新手踩坑是無法避免,最近就遇到了一個比較難的問題: 一般情況下,要抓去網頁上某個標籤上的內容,在通過urllib下

pythongb2312/gbk編碼網頁亂碼問題

原文連結:https://blog.csdn.net/junli_chen/article/details/50082795  做了個網路爬蟲抓取網頁,但如果網頁是gbk/gb2312編碼,則會出現亂碼問題,如下: 取得文字後,直接列印,輸出結果str如下:¹óÖÝÈËÊ¿¼ÊÔÐÅ

在使用python的selenium庫 動態網頁時,瀏覽器內容出現空白的解決方式

轉載請標明出處,謝謝~。 我使用的版本: 1、python 3.7 (IDE 用的 pycharm) 2、selenium(通過pip install 安裝的最新版本:3.14 時間:2018.9.6 ) 3、 geckodriver.exe 21.0 4、fi

給大家分享一篇 用Python漫畫製作mobi格式電子書

  想看某一部漫畫,但是用手機看感覺螢幕太小,用電腦看吧有太不方面。正好有一部Kindle,決定寫一個爬蟲把漫畫爬取下來,然後製作成 mobi 格式的電子書放到kindle裡面看。 一、編寫爬蟲程式   用Chrome瀏覽器開啟目標網站,按下F12 啟動“開

Python爬蟲系列之四:利用PythonPyODPS頁面整合成PDF文件

文章架構 開發場景 在日常開發過程中, 經常需要參考一些文件。對於線上文件,往往由於網速等原因,用起來總不是那麼(ma)順(fan)心。 開發工具 Anaconda Python 2 實現方案 基於 bs4 模組標籤解析 爬取