1.动机

对于知乎的一些高知大V,他们的回答总是那么具有说服力,通过阅读他们的回答,了解他们对热点事件的分析方式,通过现象看本质,一不至于被带节奏,二增加自己的知识面。多读多看,大有裨益。那如果在网络信号不太好或不舍得太多流量的情况下(穷),能够翻看他们的回答就太好了。

本篇介绍一下如何把”恶喵的奶爸“知乎回答页全部下载下来并保存为一个PDF。

1.1.分析

实现方式一,获取全部HTML源代码,将多个HTML文件合成一个HTML文件,将最后合成的这个文件保存为PDF。

实现方式二,将单个HTML文件保存为PDF,再将多个PDF合成一个。

经分析,后者更容易实现。

在正式爬之前,多做一些本地的测试,在本地能够行得通,再去骚扰目标网站。这样做的目的,一是不让网站运营者恶心;二是节约自己的时间和精力,因为大型网站大多有自己的反爬措施,频繁骚扰两三次,ip就被封了,那还要考虑换ip等一系列问题。

2.将本地HTML保存为PDF文件

先用selenium访问以下目标网站,将源代码保存到本地HTML,然后用本地的HTML做测试。

# -*- coding: utf-8 -*-

# @AuThor : frank_lee

import pdfkit

htmlfile = open("zhihu_answer.html", 'r', encoding='utf-8')

confg = pdfkit.configuration(wkhtmltopdf=r'D:\htmlpdf\wkhtmltopdf\bin\wkhtmltopdf.exe')

pdfkit.from_url(htmlfile, 'zhihu.pdf', configuration=confg)

2.1.上面代码能够正常执行的先决条件--安装wkhtmltopdf、pdfkit

根据自己的操作系统下载对应的版本即可。安装完成后可以将其加入到环境变量中,也可以不加入,但每次使用时需要调用wkhtmltopdf.exe的绝对路径。

2.2.2.安装pdfkit模块

pip install pdfkit

3.将一个本地HTML文件保存为多个PDF文件

import pdfkit

import time

i = 0

while i < 4:

# pdfname = "zhihu{}".format(i)+".pdf"

htmlfile = open("zhihu_answer.html", 'r', encoding='utf-8')

confg = pdfkit.configuration(wkhtmltopdf=r'D:\htmlpdf\wkhtmltopdf\bin\wkhtmltopdf.exe')

pdfkit.from_url(htmlfile, "zhihu{}".format(i)+".pdf", configuration=confg)

i += 1

time.sleep(10)

while循环和for循环都可以实现,但是如果这样写,只会保存为一个完整的PDF文件,剩下的都是空白PDF:

# -*- coding: utf-8 -*-

# @AuThor : frank_lee

import pdfkit

import time

htmlfile = open("zhihu_answer.html", 'r', encoding='utf-8')

confg = pdfkit.configuration(wkhtmltopdf=r'D:\htmlpdf\wkhtmltopdf\bin\wkhtmltopdf.exe')

i = 0

while i < 4:

# pdfname = "zhihu{}".format(i)+".pdf"

pdfkit.from_url(htmlfile, "zhihu{}".format(i)+".pdf", configuration=confg)

i += 1

time.sleep(10)

所以要注意代码的执行顺序。

4.将多个PDF文件合成一个PDF文件

# -*- coding: utf-8 -*-

# @AuThor : frank_lee

import os, PyPDF2

# 找出所有的pdf文件,并将文件名保存至列表。

filelist = []

for filename in os.listdir('./dir-with-pdfs'):

if filename.endswith('.pdf'):

filelist.append(filename)

# 创建一个新的pdf

newPdfFile = PyPDF2.PdfFileWriter()

# 循环打开每一个pdf文件,将内容添加至新的pdf

for filename in filelist:

pdfFile = open('./dir-with-pdfs/' + filename, 'rb')

pdfObj = PyPDF2.PdfFileReader(pdfFile)

# 获取页数

pageNum = pdfObj.numPages

for num in range(0, pageNum):

pageContent = pdfObj.getPage(num)

newPdfFile.addPage(pageContent)

newFile = open('zhihu_emiao.pdf', 'wb')

newPdfFile.write(newFile)

newFile.close()

5.动真格的

在上一篇的基础上,添加登录功能,因为知乎有些有些大V的回答页面不登录就能访问,有些则不行。

5.1.模拟登录

如果能够避开验证码实现登录,岂不是很轻松,哎,想一下还蛮激动,试一下使用selenium结合浏览器开发者模式还真可以,关键代码如下:

options = webdriver.ChromeOptions()

options.add_experimental_option(

'excludeSwitches', ['enable-automation'])

self.browser = webdriver.Chrome(options=options)

在该模式下,可以完美避开验证码,直接输入用户名和密码就能实现登录。如果用户名和密码还要手动输入就太low了。此时,selenium可能会说,兄弟,显示等待了解一下。这里的代码带有“self”,因为完整代码是包含一个zhihu_infos类。如果直接定义一个函数,或者随心所欲,不定义函数,想到哪儿是哪儿,可以将其删掉。下面的代码用到了显示等待,显示等待是针对于某个特定的元素设置的等待时间,如果在规定的时间范围内,没有找到元素,则会抛出异常,如果在规定的时间内找到了元素,则直接执行,即找到元素就执行相关操作。WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.XX, 'XX')))

既然有until,自然也有until_not

WebDriverWait()一般由until()或 until_not()方法配合使用

until(method, message=' '):调用该方法提供的驱动程序作为一个参数,直到返回值为True

until_not(method, message=' '):调用该方法提供的驱动程序作为一个参数,直到返回值为False

# 等待 登录选项 出现,并点击

password_login = self.wait.until(EC.presence_of_element_located(

(By.CSS_SELECTOR, '.SignContainer-switch > span:nth-child(1)')))

password_login.click()

time.sleep(3)

# 等待 账号 出现

zhihu_user = self.wait.until(EC.presence_of_element_located(

(By.CSS_SELECTOR, '.SignFlow-accountInput > input:nth-child(1)')))

zhihu_user.send_keys(zhihu_username)

# 等待 密码 出现

zhihu_pwd = self.wait.until(

EC.presence_of_element_located(

(By.CSS_SELECTOR,

'.SignFlow-password > div:nth-child(1) > div:nth-child(1) > input:nth-child(1)')))

zhihu_pwd.send_keys(zhihu_password)

# 等待 登录按钮 出现

submit = self.wait.until(

EC.presence_of_element_located(

(By.CSS_SELECTOR, 'button.Button:nth-child(5)')))

submit.click()

time.sleep(10)

5.2.实现点击

和上篇一样,不点击,是无法查看完整回答的,不同点是这个回答页面共有20个回答,上篇是10个。

实现点击并返回网页源代码:

def get_pagesource(self, url):

self.browser.get(url=url)

self.browser.maximize_window()

time.sleep(5)

# 执行点击动作

for j in range(1, 21):

content_click = '#Profile-answers > div:nth-child(2) > div:nth-child(' + str(

j) + ') > div > div.RichContent.is-collapsed > div.RichContent-inner'

try:

complete_content = self.wait.until(

EC.presence_of_element_located(

(By.CSS_SELECTOR, content_click)))

complete_content.click()

time.sleep(1)

except BaseException:

pass

pagedata = self.browser.page_source

return pagedata

5.3.将网页源代码以.html的格式保存到本地

def save_to_html(self, base_file_name, pagedata):

filename = base_file_name + ".html"

with open(self.html_path + filename, "wb") as f:

f.write(pagedata.encode("utf-8", "ignore"))

f.close()

return filename

5.4.将已保存的HTML保存为PDF格式

def html_to_pdf(self, base_file_name, htmlname):

pdfname = base_file_name + ".pdf"

htmlfile = open(self.html_path+htmlname, 'r', encoding='utf-8')

confg = pdfkit.configuration(

wkhtmltopdf=r'D:\htmlpdf\wkhtmltopdf\bin\wkhtmltopdf.exe')

pdfkit.from_url(htmlfile, self.pdf_path + pdfname, configuration=confg)

5.5.将多个PDF文件保存为一个

def Many_to_one(self):

# 找出所有的pdf文件,并将文件名保存至列表。

filelist = []

for filename in os.listdir('./pdf_file'):

if filename.endswith('.pdf'):

filelist.append(filename)

# 创建一个新的pdf

newPdfFile = PyPDF2.PdfFileWriter()

# 循环打开每一个pdf文件,将内容添加至新的pdf

for filename in filelist:

pdfFile = open('./pdf_file/' + filename, 'rb')

pdfObj = PyPDF2.PdfFileReader(pdfFile)

# 获取页数

pageNum = pdfObj.numPages

for num in range(1, pageNum):

pageContent = pdfObj.getPage(num)

newPdfFile.addPage(pageContent)

newFile = open(self.pdf_path+'恶喵的奶爸.pdf', 'wb')

newPdfFile.write(newFile)

newFile.close()

6.完整代码

完整代码实现了将多页回答HTML格式保存为一个文件夹,PDF格式的保存到另外一个文件夹,最后将多个PDF文件合成一个PDF文件。由于代码行数较多,贴在这里不太美观,如有需要请查看github

python 知乎 合并 pdf_32.使用selenium爬取知乎,并实现多页保存为一个PDF文件相关推荐

  1. python抓取文献关键信息,python爬虫——使用selenium爬取知网文献相关信息

    python爬虫--使用selenium爬取知网文献相关信息 写在前面: 本文章限于交流讨论,请不要使用文章的代码去攻击别人的服务器 如侵权联系作者删除 文中的错误已经修改过来了,谢谢各位爬友指出错误 ...

  2. 使用Scrapy、PhantomJS和Selenium爬取知网文献摘要

    使用Scrapy.PhantomJS和Selenium爬取知网文献摘要.以下例子用于爬取"医药卫生科技"类文献摘要. 1.使用Scrapy创建项目 scrapy startproj ...

  3. python+selenium爬取链家网房源信息并保存至csv

    python+selenium爬取链家网房源信息并保存至csv 抓取的信息有:房源', '详细信息', '价格','楼层', '有无电梯 import csv from selenium import ...

  4. 练习:selenium 爬取京东的电脑商品100页的数据并保存到csv文件中

    练习:selenium 爬取京东的电脑商品100页的数据并保存到csv文件中 from selenium.webdriver import Chrome, ChromeOptions import t ...

  5. 批量爬取巨潮资讯网中“贵州茅台”相关公告的PDF文件。

    1 需求 批量爬取巨潮资讯网中"贵州茅台"相关公告的PDF文件. 2 代码实现 import reimport requests from selenium import webd ...

  6. python爬虫知乎图片_python爬虫(爬取知乎答案图片)

    python爬虫(爬取知乎答案图片) 1.⾸先,你要在电脑⾥安装 python 的环境 我会提供2.7和3.6两个版本的代码,但是本⽂只以python3.6版本为例. 安装完成后,打开你电脑的终端(T ...

  7. java+selenium爬取知网数据

    使用selenium工具爬取知网相关数据,思路:根据几个关键词搜索出相关的内容,然后爬取列表中所有论文的访问链接. 注意:直接爬取的链接是不能用的,需要自己拼接一下.具体看代码.新手,代码写的有点乱. ...

  8. python知乎爬虫收藏夹_Python爬取知乎问题收藏夹 爬虫入门

    简介 知乎的网站是比较好爬的,没有复杂的反爬手段,适合初学爬虫的人作为练习 因为刚刚入门python,所以只是先把知乎上热门问题的一些主要信息保存到数据库中,待以后使用这些信息进行数据分析,爬取的网页 ...

  9. Python爬取知网信息——Python+selenium爬取知网信息(文献名,作者,来源,发表日期,文献类型)

    # -*- coding: utf-8 -*- #时间:2019.5.1 #运行环境Python 3.* ''' 1.运行此代码前需要先下载Chrome浏览器,去百度搜索下载 2.我是利用seleni ...

最新文章

  1. 成熟的AI应该自己写代码,IBM发布5亿行代码数据集,包含55种语言|开源
  2. 计算机组成原理学习笔记(一)
  3. 常用16种视图切换动画
  4. DHL 快递跟踪查询
  5. JDBC笔记-李伟杰版
  6. Java虚拟机专题之内存分配(读书笔记)
  7. 音乐播放小窗口html,jQuery+html5迷你网页音乐播放器代码
  8. 交换机vlan划分实验
  9. 对格斗游戏的一点想法
  10. mapgis明码文件转为点线面文件_Geomap格式转化.doc
  11. 全新版大学英语综合教程第一册学习笔记(原文及全文翻译)——7 - Kids On The Track(生死时刻)
  12. [转]stm32 sdio写入速度 SD卡【好文章】[F1开发板通用] 战舰STM32F103开发板 SDIO写入速度测试(使用FATFS)
  13. unity3d好学吗?
  14. ddos流量攻击有多少G_攻击流量超过300G,遭遇DDoS时我们能做些什么?
  15. adb 查看指定APP日志
  16. 神奇的手指——可以取代”切水果“的清屏小软件
  17. Flink学习4-流式SQL
  18. 【慧河网络安全组】Web基础题解培训
  19. Web安全-泛微相关系统-历史漏洞
  20. springboot的学习记录

热门文章

  1. ArrayList 的三种构造方法
  2. 有趣的二进制—高效位运算
  3. react系列之isMounted is an Antipattern
  4. linux php -r,了解Linux
  5. 挑战程序设计竞赛(第2版) 第3章笔记
  6. tcp/ip协议初识
  7. linux删除编译中间件,关于linux 里安装编译环境和中间件
  8. web.xml中配置DispatcherServlet前端控制器和CharacterEncodingFilter字符过滤器后web-app标签显红报错
  9. Ubuntu 硬盘”分区“图文教程(用于光盘,U盘安装Ubuntu)
  10. java客户端操作elasticsearch7.3.2版本