0
点赞
收藏
分享

微信扫一扫

Python爬虫系列之四:利用Python爬取PyODPS页面并整合成PDF文档


文章架构

Python爬虫系列之四:利用Python爬取PyODPS页面并整合成PDF文档_PyPDF2

开发场景

  • 在日常开发过程中, 经常需要参考一些文档。对于在线文档,往往由于网速等原因,用起来总不是那么(ma)顺(fan)心。
  • 博文以爬取​​PyODPS Docs​​​ 为例,整理页面爬取、转换(​​PDFKit​​​)、文档整合(​​PyPDF2​​)的过程。
  • 开发工具
  • Anaconda
  • Python 2

实现方案

  • 基于 bs4 模块标签解析
  • 爬取页面,逐层获取获取子链接
  • 弃用!未能有效获取到当前主题以及子主题 href 并且不能保证获取到的hrefs的顺序与目录层次结构相对应。
  • 基于 正则 定位获取链接
  • 有效获取所有 hrefs 并 保证其顺序与目录层次结构的一致性。

代码实现

1 获取主页链接

# coding: utf-8

# ## 爬取 PyODPS[latest] 并转换为 PDF
# - 爬取主链接
# - 根据主链接爬取子连接
# - 参考子链接爬取HTML并转换为PDF
# - 将所有 PDF 整合为一个PDF
# ---
# - 注 :
# - PyOdps PDF在线最新版本
# - 0.3.12

# In[15]:

import re
import pdfkit
import pandas as pd
from urllib import urlopen
from bs4 import BeautifulSoup

# 设置 pandas 显示参数
pd.set_option('display.width',200)
pd.set_option('display.max_rows',1000)
pd.set_option('display.max_columns',50)
pd.set_option('display.max_colwidth',500)


# ### 爬取主链接
# #### 爬取PyODPS Docs主页面

# In[9]:

url='http://pyodps.readthedocs.io/zh_CN/latest/index.html'
html=urlopen(url).read().decode('utf8')
soup=BeautifulSoup(html,'lxml')


# #### 取值最新文档首页 API及标题

# In[10]:

# 主链接 (API)
api=soup.find(name='link', attrs={'rel':'canonical'}).get('href')
# 获取文档标题
title=soup.find('link',attrs={"href":"#","rel":"top"}).get('title').replace(' ','_')

# 获取首页超链接 (href)
hrefs=[]
div_s=soup.find_all(name='div',attrs={'aria-label':'main navigation','role':'navigation'})[0]
for tag_a in div_s.find_all(name='a',attrs={'class':'reference internal'}):
content_name=tag_a.get_text()
url=api+tag_a.get('href')
hrefs.append([content_name,url])


# #### 美化 DataFrame 显示效果函数

# In[20]:

'''
设置悬停效果
'''
def hover(hover_color="#ffff99"):
return dict(selector="tr:hover",
props=[("background-color", "%s" % hover_color)])
'''
美化DataFrame显示效果
'''
def display_prettify(df):
from IPython.display import HTML

styles = [
hover(),
dict(selector="th", props=[("font-size", "100%"),
("text-align", "center")]),
dict(selector="td", props=[("text-align", "left")]),
dict(selector="caption", props=[("caption-side", "left")])
]
return df.style.set_table_styles(styles).set_caption("Hover to highlight.")


# #### 首页超连接(href)打印显示

# In[13]:

df=pd.DataFrame(hrefs, columns=['content_name','href'])

display_prettify(df)

2 参考主链接,获取子链接

# ### 根据主链接爬取子连接

# In[ ]:

hrefs_2=[] # 有序列表,存储主、子链接并与文档目录层次结构保持一致性

for name,url in hrefs:
if url not in [hf[1] for hf in hrefs_2]: # href 不在 hrefs_2中,则追加
hrefs_2.append([name,url])
t_html=urlopen(url).read().decode('utf8')

# 根据正则表达式 查找当前目录主题
f_re='<a class="current reference internal".*?</a><ul>(.*?)</ul>'
if len(re.findall(f_re, t_html, re.I|re.S|re.M)) !=0 :
target_s = re.findall(f_re, t_html, re.I|re.S|re.M)[0]

# 根据正则表达式 获取当前子主题链接
t_re='<a class="reference internal" href="(.*?)">(.*?)</a>'
for href,name in re.findall(t_re, target_s, re.I|re.S|re.M):
if href.strip().endswith('.html'):
hrefs_2.append([name,api+href])


# In[22]:

display_prettify(pd.DataFrame(hrefs_2))


# #### 显示PyODPS 所有链接

# In[105]:

3 根据链接,爬取页面并转换为 PDFs

# ### 参考子链接爬取HTML并转换为PDF

# In[24]:

for name,href in hrefs_2:
pdfkit.from_url(href,'./tmp/'+name+'.pdf')

4 通过 ​​PdfFileMerger​​ 整合 PDF

from PyPDF2 import PdfFileMerger

# 创建 PdfFileMerger 对象,合并PDFs
merger = PdfFileMerger()
for name, url in hrefs_2:
t_input = open('./tmp/'+name+'.pdf', 'rb')
merger.append(t_input)

# 流输出
output = open(title+".pdf", "wb")
merger.write(output)

# 关闭文件流
output.close()
merger.close()

脚本链接

  • ​​Python_PyODPS_HTML_to_PDF​​

Reference Links

  • ​​PyODPS​​
  • ​​The OnlinePyODPS PDF 0.3.12​​
  • But the latest is0.7.14
  • ​​PyPDF2.utils.PdfReadError:Unexpected destination ‘/WKANCHOR_2’​​
  • ​​Python将HTML转PDF​​
  • ​​pdfkit 0.6.1​​
  • ​​Home page for the PyPDF2 project​​
  • ​​wkhtmltopdf’s github link​​


举报

相关推荐

0 条评论