1. 程式人生 > >Python爬蟲系列之四:利用Python爬取PyODPS頁面並整合成PDF文件

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

文章架構

arctile_schema

開發場景

  • 在日常開發過程中, 經常需要參考一些文件。對於線上文件,往往由於網速等原因,用起來總不是那麼(ma)順(fan)心。
  • 開發工具
    • 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]:

pd.DataFrame(hrefs_2)
3 根據連結,爬取頁面並轉換為 PDFs
# ### 參考子連結爬取HTML並轉換為PDF

# In[24]:

for name,href in hrefs_2:
    pdfkit.from_url(href,'./tmp/'+name+'.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()

指令碼連結