<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>

          搞定,爬取公眾號(hào)文章轉(zhuǎn)換成PDF,自動(dòng)郵件發(fā)送給自己!

          共 15806字,需瀏覽 32分鐘

           ·

          2021-05-09 01:53

          ↑↑↑關(guān)注后"星標(biāo)"簡(jiǎn)說Python

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

          大家好,我是老表!
          今天給大家分享如何每天定時(shí)爬取公眾號(hào)文章鏈接和標(biāo)題,并將內(nèi)容轉(zhuǎn)換成PDF,以附件的形式通過郵件發(fā)送給自己的小技巧(腳本)。

          一、寫在前面

          這也是一個(gè)讀者的需求,之前也有讀者提到過,趁五一還在假期中(調(diào)休幾天),給大家一并解決了,拿到需求,先簡(jiǎn)單分析下,然后百度下,基本解決方法就有了,哈哈哈哈!

          最后呈現(xiàn)效果:

          本需求主要分為三個(gè)部分:

          • 爬取到公眾號(hào)發(fā)布文章的鏈接和標(biāo)題

          這塊,目前網(wǎng)絡(luò)上有的一些方法有:從搜狗微信上爬?。ㄓ袀€(gè)現(xiàn)成的框架wechatsogou[1],不過好像已經(jīng)好久沒人維護(hù)了,鏈接獲取功能測(cè)試失?。?、從微信公眾號(hào)后臺(tái)爬取(需要大家注冊(cè)微信公眾號(hào),麻煩),這里我用的方法是直接從第三方數(shù)據(jù)平臺(tái)爬?。ê?jiǎn)單)。

          我選擇了志軍大佬開發(fā)的二十次冪平臺(tái)[2],這里也給大家安利下這個(gè)網(wǎng)站,除了一些公眾號(hào)主可以用,讀者朋友也可以在上面查看全網(wǎng)熱文以及喜歡的公眾號(hào)的歷史文章等。

          • 將公眾號(hào)鏈接內(nèi)容轉(zhuǎn)換為pdf

          這里利用pdfkit這個(gè)庫(kù),避免直接通過url轉(zhuǎn)換成pdf時(shí)出現(xiàn)的無法顯示圖片問題,我們本次引用了wechatsogou[1]中的get_article_content函數(shù),將url中的代碼提取出來轉(zhuǎn)換為html字符串,具體源碼我簡(jiǎn)單看了下,有興趣的也可以私聊我一起研究下(空閑的時(shí)候)。

          • 通過郵件將pdf以附件形式發(fā)送

          這一步蠻簡(jiǎn)單的,利用yagmail模塊實(shí)現(xiàn)郵件發(fā)送功能,在開始前,我們需要先在對(duì)應(yīng)郵箱的設(shè)置中打開POP3/SMTP服務(wù),這樣才能使用,不然會(huì)提示沒有權(quán)限。

          二、基本知識(shí)概要

          • 爬蟲,利用requests發(fā)送get請(qǐng)求 requests.get(url,headers=headers)
          • json將json格式字符串轉(zhuǎn)為Python字典格式 json.loads(json_string)
          • 基本反爬和反反爬策略
          • pdfkit將文本內(nèi)容或者url鏈接內(nèi)容轉(zhuǎn)換成pdf
          • wechatsogou搜狗微信爬蟲框架
          • 正則表達(dá)式re.sub函數(shù)和字符串處理函數(shù)replace
          • yagmail.SMTP自動(dòng)發(fā)送郵件
          • markdown語法寫郵件內(nèi)容(格式)
          • 字符串傳多個(gè)參數(shù)format函數(shù)
          • os模塊基本操作,獲取當(dāng)前文件目錄、創(chuàng)建文件夾等
          • datetime模塊獲取當(dāng)前日期并前推一天
          • sys模塊exit()結(jié)束當(dāng)前程序

          等。。。

          三、開始動(dòng)手動(dòng)腦

          3.1 本次項(xiàng)目需要導(dǎo)入的庫(kù)

          import requests   # 發(fā)送get/post請(qǐng)求,獲取網(wǎng)站內(nèi)容
          import wechatsogou   # 微信公眾號(hào)文章爬蟲框架
          import json   # json數(shù)據(jù)處理模塊
          import datetime   # 日期數(shù)據(jù)處理模塊
          import pdfkit  # 可以將文本字符串/鏈接/文本文件轉(zhuǎn)換成為pdf
          import os   # 系統(tǒng)文件管理
          import re  # 正則匹配模塊
          import yagmail  # 郵件發(fā)送模塊
          import sys  # 項(xiàng)目進(jìn)程管理

          3.2 爬取到公眾號(hào)發(fā)布文章的鏈接和標(biāo)題

          '''
          1、從二十次冪獲取公眾號(hào)最新的推文鏈接和標(biāo)題
          '''

          def get_data(publish_date):
              # 添加Cookie 記錄登錄狀態(tài)
              header = {
                  'Cookie'"獲取方法見下文" 
              }
              # 可以自定義設(shè)置獲取文章的發(fā)布時(shí)間區(qū)間,日期越多,獲取到的文章越多,本項(xiàng)目默認(rèn)獲取前一天的數(shù)據(jù)
              start_at = publish_date
              end_at = publish_date  # 每次只爬去前一天的數(shù)據(jù)
              url1 = 'https://www.ershicimi.com/api/stats/articles?'
              # bid=EOdxnBO4 表示公眾號(hào) 簡(jiǎn)說Python,每個(gè)公眾號(hào)都有對(duì)應(yīng)的bid,可以直接搜索查看
              url2 = 'page=1&page_size=50&bid=EOdxnBO4&start_at={0}&end_at={1}&position=all'.format(start_at,end_at)
              url3 = url1+url2
              r = requests.get(url3, headers=header)

              json_data = json.loads(r.text)
              html_data = json_data['data']['articles']
          #     print(html_data)
              return html_data

          如何獲取你自己登錄二十次冪后的Cookie:首先我們需要知道為什么需要這個(gè)玩意。我們?nèi)绻苯釉L問我上面提供的鏈接會(huì)發(fā)現(xiàn)print(html_data)出來的是登錄頁(yè)面的源碼,這也是一個(gè)比較基本的反爬手段--需要登錄后才可以訪問網(wǎng)站內(nèi)的數(shù)據(jù)。

          針對(duì)這個(gè)反爬手段,最簡(jiǎn)單的反反爬蟲手段就是手動(dòng)登錄后獲取Cookie,這里會(huì)記錄我們的登錄信息,讓我們?cè)僭L問這類頁(yè)面的時(shí)候讓系統(tǒng)以為我們是已經(jīng)登錄過了的人,不過Cookie是有時(shí)效的,所以這種方法還蠻麻煩的。

          還有種簡(jiǎn)單方法,直接通過代碼傳參,然后登錄二十次冪,保持Session,然后再去訪問我們想訪問的數(shù)據(jù)頁(yè)面就可以了,這個(gè)我簡(jiǎn)單的利用requests.session()試了下,沒成功,有興趣的同學(xué)可以試試,這樣就不用每天運(yùn)行代碼前還需要手動(dòng)到頁(yè)面登錄獲取Cookie,歡迎試成功的同學(xué)在評(píng)論區(qū)或者微信和我分享下,我也會(huì)第一時(shí)間和大家分享。

          手動(dòng)獲取Cookie方法:1)注冊(cè)好二十次冪后(網(wǎng)站地址見文末參考鏈接注釋),在登錄頁(yè)面填寫賬號(hào)相關(guān)信息,點(diǎn)擊登錄按鈕登錄。2)按住F12調(diào)出瀏覽器的開發(fā)者工具,選擇Network,然后刷新頁(yè)面,在Network會(huì)出現(xiàn)網(wǎng)頁(yè)加載過程中的一些內(nèi)容,找到下圖中打紅框的login?next=%2Fsearch%2Faccount,點(diǎn)擊一下,右側(cè)就會(huì)出現(xiàn)請(qǐng)求相關(guān)信息,找到Request Headers中的Cookie后對(duì)應(yīng)的一長(zhǎng)串字符串就是我們需要的Cookie值。

          3.3 將公眾號(hào)鏈接內(nèi)容轉(zhuǎn)換為pdf

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

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

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

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

          這里為了解決pdfkit直接轉(zhuǎn)換url成為pdf會(huì)出現(xiàn)圖片無法顯示問題,參考了博客園xuzifan[3]提供的思路,利用wechatsogou中的get_article_content函數(shù),將url中的代碼提取出來轉(zhuǎn)換為html字符串,然后將html字符串轉(zhuǎn)換為pdf,完美解決。

          這里需要注意的是:使用pdfkit需要提前訪問wkhtmltopdf下載地址[4]下載并安裝好wkhtmltopdf。如果是mac蠻簡(jiǎn)單的,直接下載安裝即可,如果是windows需要下載安裝后將安裝路徑添加到系統(tǒng)環(huán)境變量中或者修改轉(zhuǎn)換pdf代碼(如下)。

          config=pdfkit.configuration(wkhtmltopdf='你的wkhtmltopdf安裝路徑'))   
          pdfkit.from_string(html, targetPath + os.path.sep + filename + '.pdf', configuration=config)

          3.4 通過郵件將pdf以附件形式發(fā)送

          '''
          3、通過郵件將新生成的文件發(fā)送到自己的郵箱
          '''

          def send_email(user_name, email, gzh_data):
              yag = yagmail.SMTP(user='你的郵箱',password='你的POP3/SMTP服務(wù)密鑰',host='smtp.163.com')
              contents = ['親愛的 '+user_name+' 你好:<br>',
                          '公眾號(hào) {0} {1}發(fā)布了{(lán)2}篇推文,推文標(biāo)題分別為:<br>'.format(gzh_data['gzh_name'], gzh_data['publish_date'], len(gzh_data['save_path'])),
                          '<br>'.join(gzh_data['save_path']),
                          '<br>文章詳細(xì)信息可以查看附件pdf內(nèi)容,有問題可以在公眾號(hào)%s聯(lián)系作者提問。<br>'%gzh_data['gzh_name'],
                          '<br><br><p align="right">公眾號(hào)-%s</p>'%gzh_data['gzh_name']
                          ]
              # 在郵件內(nèi)容后,添加上附件路徑(蠻簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加附件,直接拼接兩個(gè)列表即可哈哈哈哈)
              contents = contents + [targetPath + os.path.sep + i + '.pdf' for i in gzh_data['save_path']]
              yag.send(email, '請(qǐng)查看'+gzh_name+publish_date+'推文內(nèi)容', contents)

          yagmail可以實(shí)現(xiàn)簡(jiǎn)單的自動(dòng)發(fā)送郵件功能,我也拿來做過批量發(fā)送,蠻好用的,還支持markdown語法對(duì)郵件內(nèi)容進(jìn)行排版,蠻好的。

          yag = yagmail.SMTP(user='你的郵箱',password='你的POP3/SMTP服務(wù)密鑰',host='smtp.163.com')

          這里需要注意的是,代碼里的user就是你的郵箱地址,比如[email protected],password不是你的郵箱密碼,而是你在郵箱頁(yè)面開啟POP3/SMTP服務(wù)后,系統(tǒng)給到的一個(gè)碼,下面以163郵箱為例子給大家介紹如何獲取這個(gè)password。

          1)在網(wǎng)站登錄對(duì)應(yīng)的郵箱;

          2)點(diǎn)擊設(shè)置按鈕,然后選擇POP3/SMTP/IMAP,進(jìn)入到相關(guān)設(shè)置頁(yè)面。

          3)點(diǎn)擊POP3/SMTP服務(wù)后的 開啟 按鈕,然后驗(yàn)證下即可,完成后會(huì)有彈框提示,授權(quán)密碼就是我們要的password。

          3.5 定時(shí)每天自動(dòng)執(zhí)行程序

          今天回杭州,路上寫了一天,顛顛倒倒,這個(gè)功能就開放留給大家啦,大家寫出后可以留言區(qū)將自己的方案寫上,第一個(gè)給出方案的讀者朋友可以獲得Python自動(dòng)化測(cè)試相關(guān)圖書一本。

          全部代碼:

          import requests   # 發(fā)送get/post請(qǐng)求,獲取網(wǎng)站內(nèi)容
          import wechatsogou   # 微信公眾號(hào)文章爬蟲框架
          import json   # json數(shù)據(jù)處理模塊
          import datetime   # 日期數(shù)據(jù)處理模塊
          import pdfkit  # 可以將文本字符串/鏈接/文本文件轉(zhuǎn)換成為pdf
          import os   # 系統(tǒng)文件管理
          import re  # 正則匹配模塊
          import yagmail  # 郵件發(fā)送模塊
          import sys  # 項(xiàng)目進(jìn)程管理


          '''
          1、從二十次冪獲取公眾號(hào)最新的推文鏈接和標(biāo)題
          '''

          def get_data(publish_date):
              # 添加Cookie 記錄登錄狀態(tài)
              header = {
                  'Cookie'"獲取方法見上文介紹"
              }
              # 可以自定義設(shè)置獲取文章的發(fā)布時(shí)間區(qū)間,日期越多,獲取到的文章越多,本項(xiàng)目默認(rèn)獲取前一天的數(shù)據(jù)
              start_at = publish_date
              end_at = publish_date  # 每次只爬去前一天的數(shù)據(jù)
              url1 = 'https://www.ershicimi.com/api/stats/articles?'
              # bid=EOdxnBO4 表示公眾號(hào) 簡(jiǎn)說Python,每個(gè)公眾號(hào)都有對(duì)應(yīng)的bid,可以直接搜索查看
              url2 = 'page=1&page_size=50&bid=EOdxnBO4&start_at={0}&end_at={1}&position=all'.format(start_at,end_at)
              url3 = url1+url2
              r = requests.get(url3, headers=header)

              json_data = json.loads(r.text)
              html_data = json_data['data']['articles']
          #     print(html_data)
              return html_data


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

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

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

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

          '''
          3、通過郵件將新生成的文件發(fā)送到自己的郵箱
          '''

          def send_email(user_name, email, gzh_data):
              yag = yagmail.SMTP(user='你的發(fā)郵件的郵箱,可以和收件的是一個(gè)',password='你的POP3/SMTP服務(wù)密鑰',host='smtp.163.com')
              contents = ['親愛的 '+user_name+' 你好:<br>',
                          '公眾號(hào) {0} {1}發(fā)布了{(lán)2}篇推文,推文標(biāo)題分別為:<br>'.format(gzh_data['gzh_name'], gzh_data['publish_date'], len(gzh_data['save_path'])),
                          '<br>'.join(gzh_data['save_path']),
                          '<br>文章詳細(xì)信息可以查看附件pdf內(nèi)容,有問題可以在公眾號(hào)%s聯(lián)系作者提問。<br>'%gzh_data['gzh_name'],
                          '<br><br><p align="right">公眾號(hào)-%s</p>'%gzh_data['gzh_name']
                          ]
              # 在郵件內(nèi)容后,添加上附件路徑(蠻簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加附件,直接拼接兩個(gè)列表即可哈哈哈哈)
              contents = contents + [targetPath + os.path.sep + i + '.pdf' for i in gzh_data['save_path']]
              yag.send(email, '請(qǐng)查看'+gzh_name+publish_date+'推文內(nèi)容', contents)
              


          # 程序開始
          # 0、為爬取內(nèi)容創(chuàng)建一個(gè)單獨(dú)的存放目錄
          gzh_name = '簡(jiǎn)說Python'  # 爬取公眾號(hào)名稱
          targetPath = os.getcwd() + os.path.sep + gzh_name
          # 如果不存在目標(biāo)文件夾就進(jìn)行創(chuàng)建
          if not os.path.exists(targetPath):
              os.makedirs(targetPath)
          print('------pdf存儲(chǔ)目錄創(chuàng)建成功!')
              
          # 1、從二十次冪獲取微信公眾號(hào)最新文章數(shù)據(jù) 
          year = str(datetime.datetime.now().year)
          month = str(datetime.datetime.now().month)
          day = str(datetime.datetime.now().day-1)
          publish_date = datetime.datetime.strptime(year+month+day,'%Y%m%d').strftime('%Y-%m-%d')  # 文章發(fā)布日期
          html_data = get_data(publish_date)
          if html_data:
              print('------成功獲取到公眾號(hào){0}{1}推文鏈接!'.format(gzh_name, publish_date))
          else:
              print('------公眾號(hào){0}{1}沒有發(fā)布推文,請(qǐng)前往微信確認(rèn)'.format(gzh_name, publish_date))
              sys.exit()  # 結(jié)束進(jìn)程
              

          # 2、for循環(huán)遍歷,將每篇文章轉(zhuǎn)化為pdf
          save_path = []
          for article in html_data:
              url = article['content_url']
              title = article['title']
              # 將文章鏈接內(nèi)容轉(zhuǎn)化為pdf,并記錄存儲(chǔ)路徑,用于后面郵件發(fā)送附件
              save_path.append(url_to_pdf(url, title, targetPath, publish_date)) 
          print('------pdf轉(zhuǎn)換保存成功!')
              
          # 3、通過郵件將新生成的文件發(fā)送到自己的郵箱
          user_name = '收件人名稱' # 可以寫自己的名字
          email = '收件郵箱地址'
          gzh_data = {
              'gzh_name':gzh_name,
              'publish_date':publish_date,
              'save_path':save_path
          }
          send_email(user_name, email, gzh_data)
          print('------郵件發(fā)送成功啦!')

          隨便說說

          我的五一也結(jié)束啦,祝大家明天周末愉快。

          最重要的是明天是母親節(jié),在這里祝我的媽媽節(jié)日快樂,身體健康,其他的話單獨(dú)和媽媽說(嘿嘿),也祝天下所有母親節(jié)日快樂。

          另外大家如果有什么類似需求,或者想要本文所有相代碼的ipynb文件,可以掃下方二維碼添加我的微信,查看朋友圈獲取。
          歡迎大家進(jìn)行學(xué)習(xí)交流。

          參考鏈接

          • wechatsogou:https://github.com/Chyroc/WechatSogou
          • 二十次冪平臺(tái):https://www.ershicimi.com/
          • 博客園xuzifan:https://www.cnblogs.com/xuzifan/p/11121878.html
          • wkhtmltopdf下載地址:https://wkhtmltopdf.org/downloads.html

          --END--


          掃碼即可加我微信

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


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

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

          瀏覽 105
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  大陆91视频 | 红桃视频波多野结衣 | 久久免费小电影 | 性爱视频网站久久 | 久久久久久99精品无码 |