[实作教学]使用Line Notify收到Dcard最新文章通知

透过官方帐号进行推播会因为人数越来越多而增加发送成本,因此 Line Notify是一个官方提供帐号来传送通知,重要的是免费!!

首先登入到 LINE Notify 并进入到个人页面~

选择要接收通知的聊天室

把产生的权证记录下来,如果遗失或忘记的话就只能重新连接获取新的权证

这样到这边 Line Notify 的设定就完成了,接着看程序码
https://github.com/hardy1234554321/shockuccu-linenotify

使用到的 python 模组

  • requests:建立与 Dcard 之间连线,获取我们要的网页资料
  • bs4:BeautifulSoup是一个用来解析HTML结构的Python套件
  • re:利用正则表达式分析url
  • time:用 time.sleep() 进行睡眠,降低发送 request 频率
  • datetime:取得当前时间
  • sqlite3:简单纪录文章资讯

设定 Line Notify 参数设定

  • token:传送权证
  • message:传送要发送的讯息
  • img:传送要发送的图片url
  • isNotificationDisabled :是否要收到通知
def lineNotifyMessage(token, message, img, isNotificationDisabled = False):
    headers = {
        "Authorization": "Bearer " + token,
        "Content-Type": "application/x-www-form-urlencoded"
    }

    payload = {
        'message': message,
        'imageThumbnail': img,
        'imageFullsize': img,
        'notificationDisabled': isNotificationDisabled
    }

    r = requests.post("https://notify-api.line.me/api/notify",
                      headers=headers, params=payload)
    print(r.status_code)
    time.sleep(1)

分析 Dcard 网页资讯

def spider_dcard_sex(token):
    my_headers = {
        'cookie': 'over18=1;'
    }
    list_url = 'https://www.dcard.tw/f/sex?latest=true'
    response = requests.get(list_url, headers=my_headers)
    soup = bs4.BeautifulSoup(response.text, "html.parser")

    articles = soup.find_all('a')
    for ar in articles:
        article_url = 'https://www.dcard.tw%s' % ar.get('href')
        if '/f/sex/p/' not in article_url:
            continue

        # 检查是否发送过
        sql = "SELECT * FROM articles WHERE a_url = '%s'" % article_url
        c.execute(sql)
        result = c.fetchone()
        if result != None:
            print('暂无新文章 %s' % datetime.datetime.now())
            time.sleep(1)
            continue

        # 载入文章
        response = requests.get(article_url)
        soup = bs4.BeautifulSoup(response.text, "html.parser")

        # 检查文章有没有不见
        content = soup.find('h1', 'sc-7mzcsk-2')
        if content:
            if content.string == 'Oh!文章不见了':
                continue

        # 标题
        h1_title = soup.find('h1', 'sc-1932jlp-0')
        title = h1_title.text

        img_list = []
        for img_url in soup.find_all('img'):
             # 只抓图档连结
            result = re.findall(
                'https?://imgur.dcard.tw?\S+?/\S+?\.(?:jpg|gif|png)', img_url.get('src'))
            if len(result) == 0:
                continue
            img_list.append(result[0])

        # 内容转文字
        content = '\n'.join(img_list)

        # 显示
        msg = '\n'
        msg += '\n标题:%s' % title
        msg += '\n网址:%s' % article_url
        print(msg)
        lineNotifyMessage(token=token, message=msg, img='')

        # 纪录文章资讯
        sql = "INSERT INTO 'articles' ('id','a_url','a_author','a_title','a_type') VALUES (NULL,'%s','%s','%s','%s')" % (
            article_url, 'dcard', title, 'DCARD')
        c.execute(sql)
        conn.commit()

        for img_url in img_list:
            img_msg = '\n%s' % (img_url)
            print(img_msg)
            lineNotifyMessage(token=token, message=img_msg, img=img_url, isNotificationDisabled=True)
            time.sleep(1)

把 <access_token> 替换为刚刚的权证就完成了

if __name__ == "__main__":
    while (1):
        # create DATABASE
        conn = sqlite3.connect('db/shockuccu.db')
        c = conn.cursor()

        # create TABLE
        sql = "CREATE TABLE IF NOT EXISTS 'articles' (\
                'id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\
                'a_url' TEXT NOT NULL,\
                'a_author' TEXT NOT NULL,\
                'a_title' TEXT NOT NULL,\
                'a_type' TEXT NOT NULL\
            )"
        c.execute(sql)
        conn.commit()

        # Dcard西斯版
        token = '<access_token>'
        spider_dcard_sex(token)

        conn.close()

接下来就只要感谢大大无私分享、楼主好人一生平安~~

技术文章笔记
https://shockuccu.blogspot.com/2021/10/line-notifydcard.html


<<:  [新手教学]如何使用Line Notify

>>:  Test / Validation 对中文使用者的困惑

[Day-11] 巢状式if小练习

上次练习完巢状式if 这次出了简单的练习题来练习 那现在开始我今天的练习吧~ 题目:判断输入的数字是...

Day.11 搞懂主从架构- 主从复制(Master Slave Replication)

在前一篇我们提到binlog可以当作资料恢复的重要纪录,今天要介绍的是binlog另一个主要功能用...

Spring Framework X Kotlin Day 17 Reactive

GitHub Repo https://github.com/b2etw/Spring-Kotlin...

Day 23:专案05 - KKBOX风云榜02 | AJAX

昨天已经找到的KKBOX用来传资料的API,也知道各个参数的意义了,今天就实际将资料抓下来吧! 歌...

[Day 15]呐呐,还有一半别想跑(前端篇)

挑战目标: MockNative Camp 今天继续来制作我们的Footer, 目标 前两天我们已经...