<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          肝|打補丁,順便拓展下爬取公眾號歷史文章合并成一個PDF

          共 14474字,需瀏覽 29分鐘

           ·

          2021-05-13 20:31

          ↑↑↑關(guān)注后"星標"簡說Python

          人人都可以簡單入門Python、爬蟲、數(shù)據(jù)分析
           簡說Python發(fā)布 
          來源:簡說Python
          作者:老表

          大家好,我是老表!
          本文是對前天發(fā)布的文章搞定,爬取公眾號文章轉(zhuǎn)換成PDF,自動郵件發(fā)送給自己!的修正。

          寫在前面

          搞定,爬取公眾號文章轉(zhuǎn)換成PDF,自動郵件發(fā)送給自己!文章發(fā)布后獲得了不少讀者朋友的好評,開心,不枉我回杭坐車一天寫下該文章,更開心的是有不少讀者朋友提出了一些問題,說明確實對大家有幫助,大家也實踐了,今天這篇文章就是對一位讀者發(fā)現(xiàn)的腳本bug的補丁。

          很巧,又是在車上寫下的?。▋蓚€下班路上+加夜工寫完本文) 看到這里先劃到文章末尾給本文點個贊和在看,留言:優(yōu)秀,不過分吧,大家的支持就是我一直肝的動力。

          開始動手動腦

          首先明確下問題,這里也感謝下讀者另外半只??提出的問題:非二十次冪會員用戶登錄后也無法從教程中的接口中獲取數(shù)據(jù),也就無法獲取到公眾號文章鏈接和標題了,我嘗試新賬號登錄后發(fā)現(xiàn)確實是這樣,之前大意了!?。?/p>

          知道問題后,我就開始想解決方法了,正好也有讀者加我微信了,問我相關(guān)問題,他已經(jīng)爬取到了微信公眾號文章鏈接和標題存在Excel中,他希望將內(nèi)容轉(zhuǎn)到word中,這我一想,這不正好互補嗎哈哈哈哈。找讀者問了下他的爬取方法,他用的是之前文章提到的從微信公眾號后臺爬取,需要大家注冊微信公眾號,比較麻煩,所以最終略過了這個方案。

          正在我一籌莫展之時,公眾號文章多了條留言。

          志軍大佬提供了個新接口,可以從https://www.ershicimi.com/a/EOdxnBO4 這里獲取公眾號文章鏈接和標題,直呼優(yōu)秀!

          分析新頁面

          https://www.ershicimi.com/a/EOdxnBO4

          訪問上方鏈接進入頁面發(fā)現(xiàn)不用登錄也能看到第一頁的數(shù)據(jù)了,直呼優(yōu)秀。(看到這里的讀者請先將 優(yōu)秀 二字 打在文末留言區(qū))

          數(shù)據(jù)都在頁面上,我們直接利用requests發(fā)送一個get請求即可。

          import requests

          # bid=EOdxnBO4 表示公眾號 簡說Python,每個公眾號都有對應(yīng)的bid,可以直接搜索查看
          url1 = 'https://www.ershicimi.com/a/EOdxnBO4'
          r = requests.get(url1)
          r.text

          接下來我們需要解析網(wǎng)頁,從其中提取出我們需要的數(shù)據(jù):

          • 最新發(fā)布文章標題
          • 最新發(fā)布文章發(fā)布時間
          • 最新發(fā)布文章對應(yīng)鏈接

          解析網(wǎng)頁提取數(shù)據(jù)的方法很多,比較常用的有正則表達式、Xpath、CSS選擇器等,網(wǎng)頁標簽十分規(guī)則,我們利用Xpath來提取數(shù)據(jù)。

          from lxml import etree
          # 把html的文本內(nèi)容解析成html對象
          html = etree.HTML(r.text)
          # xpath 根據(jù)標簽路徑提取數(shù)據(jù)
          html.xpath('//*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/h4/a/text()')

          輸出:
          [' 入門Pandas不可不知的技巧',
           ' 搞定,爬取公眾號文章轉(zhuǎn)換成PDF,自動郵件發(fā)送給自己!',
           ' PyPy為什么能讓Python原地起飛,速度比C還快!',
           ...
           ' 給大家分享一個私藏已久的Python神器!']

          這樣我們就輕松的獲取到了公眾號簡說Python近期推文的標題,接下來我們還要獲取每篇文章對應(yīng)的 發(fā)布時間和鏈接。

          在此之前我們先來說說代碼中的Xpath路徑是如何獲取到的,檢索原理是什么?

          在頁面中,我們按住F12,調(diào)出瀏覽器的開發(fā)者工具,點擊左上角的元素選擇器,然后隨便選擇頁面中的一個文章標題,選中后,開發(fā)者工具中的Elements會自動跳動到對應(yīng)的頁面源碼處,如下圖所示:

          選中源碼中對應(yīng)內(nèi)容,右鍵,選擇Copy中的Copy XPath,即可復(fù)制出對應(yīng)元素對應(yīng)的XPath路徑。

          那如何獲取到所有標題對應(yīng)的XPath路徑呢?需要一個個通過XPath路徑來獲取對應(yīng)內(nèi)容嗎?

          手動一個個復(fù)制肯定不切實際,其實很簡單,我們先按上面方法在復(fù)制一個標題的XPath路徑。

          //*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div[3]/div/h4/a

          //*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div[4]/div/h4/a

          我們來觀察下,會很快發(fā)現(xiàn)兩個路徑的區(qū)別在于倒數(shù)第二個div標簽后面的數(shù)字不同,獲取所有標題內(nèi)容的方法就是直接給一個通用的XPath路徑,直接去掉倒數(shù)第二個div后的中括號和數(shù)字即可,除此外還需要在路徑后加上/text(),這樣就可以提取出對應(yīng)的內(nèi)容了。

          //*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/h4/a/text()

          同理我們可以獲取到發(fā)布時間和對應(yīng)文章鏈接的XPath通用路徑,并獲取對應(yīng)數(shù)據(jù),將之前代碼中的get_data函數(shù)代碼改為下面的即可,其他內(nèi)容不需要修改。

          '''
          1、從二十次冪獲取公眾號最新的推文鏈接和標題(新接口,解決必須會員才看的到數(shù)據(jù)問題)
          '''

          def get_data(publish_date):
              # bid=EOdxnBO4 表示公眾號 簡說Python,每個公眾號都有對應(yīng)的bid,可以直接搜索查看
              url1 = 'https://www.ershicimi.com/a/EOdxnBO4'
              r = requests.get(url1)
              # 把html的文本內(nèi)容解析成html對象
              html = etree.HTML(r.text)
              # xpath 根據(jù)標簽路徑提取數(shù)據(jù)
              title = html.xpath('//*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/h4/a/text()')  # 標題
              publish_time = html.xpath('//*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/p[2]/@title')  # 發(fā)布時間
              title_url = html.xpath('//*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/h4/a/@href')  # 文章鏈接


              # 對數(shù)據(jù)進行簡單處理,選取最新發(fā)布的數(shù)據(jù)
              data = []
              for i in range(len(publish_time)):
                  if publish_date in publish_time[i]:
                      article = {}
                      article['content_url'] = 'https://www.ershicimi.com' + title_url[i]
                      article['title'] = title[i]
                      data.append(article)
              return data

          項目完整代碼可以查看之前的文章獲取,或者直接掃文末二維碼加我微信獲取。

          拓展需求

          爬取某個公眾號全部文章,轉(zhuǎn)成PDF教程集合

          搞定了爬取最新文章轉(zhuǎn)換成PDF,再來做爬取某個公眾號全部文章,轉(zhuǎn)成PDF教程集合就簡單多了。

          基本思路: 翻頁爬取所有文章鏈接和標題--然后依次轉(zhuǎn)換成pdf--合并所有PDF。

          根據(jù)志軍大佬提供的接口爬取第一頁是沒問題的,翻頁會提示需要登錄,參考第一篇文章解釋,直接獲取Cookie破解這個反爬蟲措施是最簡單的,模擬登錄我也看了,有個動態(tài)參數(shù)csrf_token,有興趣的同學(xué)可以看看如何破解。

          0)導(dǎo)入需要的庫
          import requests   # 發(fā)送get/post請求,獲取網(wǎng)站內(nèi)容
          import wechatsogou   # 微信公眾號文章爬蟲框架
          import datetime   # 日期數(shù)據(jù)處理模塊
          import pdfkit  # 可以將文本字符串/鏈接/文本文件轉(zhuǎn)換成為pdf
          import os   # 系統(tǒng)文件管理
          import re  # 正則匹配模塊
          import sys  # 項目進程管理
          from lxml import etree  # 把html的文本內(nèi)容解析成html對象
          import time  # 時間模塊
          from PyPDF2 import PdfFileReader, PdfFileWriter  # pdf讀取、寫入操作模塊
          1)翻頁爬取所有文章鏈接和標題

          代碼如下:

          '''
          1、從二十次冪獲取公眾號所有的推文鏈接和標題
          '''

          # 自動獲取公眾號文章總頁數(shù)
          def get_page_num():
              # bid=EOdxnBO4 表示公眾號 簡說Python,每個公眾號都有對應(yīng)的bid,可以直接搜索查看
              url1 = 'https://www.ershicimi.com/a/EOdxnBO4'
              r = requests.get(url1)
              # 把html的文本內(nèi)容解析成html對象
              html = etree.HTML(r.text)
              # xpath 根據(jù)標簽路徑提取數(shù)據(jù)
              page_num = html.xpath('//*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[2]/a/text()')
              return int(page_num[-2])  # 放回倒數(shù)第二個元素,就是總頁數(shù)


          # 將title,publish_time,content_url數(shù)據(jù)格式化成我們想要的形式
          def merge_data(title,publish_time,content_url):
              data = []
              for i in range(len(title)):
                  html_data ={}
                  html_data['title'] = title[i]
                  html_data['publish_time'] = publish_time[i]
                  html_data['content_url'] = 'https://www.ershicimi.com' + content_url[i]
                  data.append(html_data)
              return data


          # 獲取數(shù)據(jù)
          def get_data():
              # 手動獲取登錄后的Cookie 保持登錄狀態(tài)
              headers = {
                  "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
                  "Cookie":"登錄后自己獲取下,第一篇教程有詳細說明"
              }
              # bid=EOdxnBO4 表示公眾號 簡說Python,每個公眾號都有對應(yīng)的bid,可以直接搜索查看
              # 循環(huán)獲取所有數(shù)據(jù)
              page_num = get_page_num()
              html_data = []
              for i in range(page_num):
                  url1 = 'https://www.ershicimi.com/a/EOdxnBO4?page=%d'%(i+1)
                  print(url1)
                  r = requests.get(url1,headers=headers)
                  # 把html的文本內(nèi)容解析成html對象
                  html = etree.HTML(r.text)
                  # xpath 根據(jù)標簽路徑提取數(shù)據(jù)
                  title = html.xpath('//*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/h4/a/text()')  # 標題
                  publish_time = html.xpath('//*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/p[2]/@title')  # 發(fā)布時間
                  content_url = html.xpath('//*[@id="wrapper"]/div/div[2]/div[1]/div[2]/div/div[1]/div/div/h4/a/@href')  # 文章鏈接
                  html_data = html_data + merge_data(title,publish_time,content_url)
                  print("第%d頁數(shù)據(jù)獲取完成"%(i+1))
                  time.sleep(1)  # 每隔1s 發(fā)送一次請求
                  
              return html_data
          2)然后依次轉(zhuǎn)換成pdf

          代碼不變,和第一篇教程一樣。

          '''
          2、for循環(huán)遍歷,將每篇文章轉(zhuǎn)化為pdf
          '''

          # 轉(zhuǎn)化url為pdf時,調(diào)用wechatsogou中的get_article_content函數(shù),將url中的代碼提取出來轉(zhuǎn)換為html字符串
          # 這里先初始化一個WechatSogouAPI對象
          ws_api = wechatsogou.WechatSogouAPI(captcha_break_time=3

          def url_to_pdf(url, title, targetPath, publish_date):
              '''
              使用pdfkit生成pdf文件
              :param url: 文章url
              :param title: 文章標題
              :param targetPath: 存儲pdf文件的路徑
              :param publish_date: 文章發(fā)布日期,作為pdf文件名開頭(標識)
              '''

              try:
                  content_info = ws_api.get_article_content(url)
              except:
                  return False
              # 處理后的html
              html = f'''
              <!DOCTYPE html>
              <html lang="en">
              <head>
                  <meta charset="UTF-8">
                  <title>{title}</title>
              </head>
              <body>
              <h2 style="text-align: center;font-weight: 400;">{title}</h2>
              {content_info['content_html']}
              </body>
              </html>
              '''

              # html字符串轉(zhuǎn)換為pdf
              filename = publish_date + '-' + title
              # 部分文章標題含特殊字符,不能作為文件名
              # 去除標題中的特殊字符 win / \ : * " < > | ?mac :  
              # 先用正則去除基本的特殊字符,python中反斜線很煩,最后用replace函數(shù)去除
              filename = re.sub('[/:*"<>|?]','',filename).replace('\\','')
              pdfkit.from_string(html, targetPath + os.path.sep + filename + '.pdf')
              return filename  # 返回存儲路徑,后面郵件發(fā)送附件需要 
          3)合并所有PDF

          合并PDF我們使用了PyPDF2這個庫,合并pdf的需求最早是合并自己的打車發(fā)票和行程單,代碼引用了CSDN山陰少年大佬的文章Python之合并PDF文件中的代碼,這里也非常適用,就直接拿過來了。

          基本思路就是利用PyPDF2的PdfFileReader先依次讀取pdf內(nèi)容,然后利用PdfFileWriter寫入,PyPDF2更詳細用法和說明可以參考官方文檔。

          '''
          3、合并所有的pdf
          '''

          # 使用os模塊的walk函數(shù),搜索出指定目錄下的全部PDF文件
          # 獲取同一目錄下的所有PDF文件的絕對路徑
          def getFileName(filedir):

              file_list = [os.path.join(root, filespath) \
                           for root, dirs, files in os.walk(filedir) \
                           for filespath in files \
                           if str(filespath).endswith('pdf')
                           ]
              file_list.sort() # 排序
              return file_list if file_list else []

          # 合并同一目錄下的所有PDF文件
          def MergePDF(filepath, outfile):

              output = PdfFileWriter()
              outputPages = 0
              pdf_fileName = getFileName(filepath)

              if pdf_fileName:
                  for pdf_file in pdf_fileName:
          #             print("路徑:%s"%pdf_file)

                      # 讀取源PDF文件
                      input = PdfFileReader(open(pdf_file, "rb"))

                      # 獲得源PDF文件中頁面總數(shù)
                      pageCount = input.getNumPages()
                      outputPages += pageCount
          #             print("頁數(shù):%d"%pageCount)

                      # 分別將page添加到輸出output中
                      for iPage in range(pageCount):
                          output.addPage(input.getPage(iPage))

                  print("合并后的總頁數(shù):%d."%outputPages)
                  # 寫入到目標PDF文件
                  outputStream = open(os.path.join(filepath, outfile), "wb")
                  output.write(outputStream)
                  outputStream.close()
                  print("PDF文件合并完成!")

              else:
                  print("沒有可以合并的PDF文件!")

          隨便說說

          只要大家支持,老表就能無限肝,大家如果有什么類似需求,或者想要本文所有相代碼的ipynb文件,可以掃下方二維碼添加我的微信,查看朋友圈獲取。
          歡迎大家進行學(xué)習交流,需求描述越明確,被選中的機率越高。

          參考鏈接

          • wechatsogou
            https://github.com/Chyroc/WechatSogou
          • 二十次冪平臺
            https://www.ershicimi.com/
          • 博客園xuzifan
            https://www.cnblogs.com/xuzifan/p/11121878.html
          • wkhtmltopdf下載地址
            https://wkhtmltopdf.org/downloads.html
          • SDN山陰少年大佬的文章Python之合并PDF文件
            https://blog.csdn.net/jclian91/article/details/80362937
          • 搞定,爬取公眾號文章轉(zhuǎn)換成PDF,自動郵件發(fā)送給自己!
            https://mp.weixin.qq.com/s/5ESrllgYExG0VJ9giCOp0w

          --END--


          掃碼即可加我微信

          觀看朋友圈,獲取最新學(xué)習資源


          學(xué)習更多:
          整理了我開始分享學(xué)習筆記到現(xiàn)在超過250篇優(yōu)質(zhì)文章,涵蓋數(shù)據(jù)分析、爬蟲、機器學(xué)習等方面,別再說不知道該從哪開始,實戰(zhàn)哪里找了

          點贊”傳統(tǒng)美德不能丟 

          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  激情综合一色播 | 高清无码操BB网 | 做爱的网站 | 欧美另类成人在线 | 高清精品在线 |