1/30 postscript It was completed [Completed] bot that posts the start notification of Nico Nico Live Broadcasting to Discord on discord.py
This is Qiita's first post. My name is Ryo, also known as fctokyo1016. Twitter → @ fctokyo1016 I usually develop with PHP. It's a code that was made by an amateur who has been an engineer for several years, so I hope you can overlook it.
--Nico Nico Live Broadcasting Planning team to which about 10 people belong, each of whom can freely broadcast live in the same community ――Since the alert of Nico Nama can no longer be used due to the specification change, it is troublesome to find the URL when watching the broadcast of other members. ――Isn't it easier if a notification comes to the Discord server where all the members are located? --Sites such as Twitch and Youtube Live already have existing bots, but they do not support Nico Nico. ――Isn't it possible to make a fake (self-made) somehow?
--As mentioned above, due to changes in Nico Nico Live's alert specifications, neither RSS nor API support live user broadcasting.
――Can you use scraping that you touched a little in the past? ――I just wanted to study Python
-Practical Discord Bot in Python (discordpy explanation)
The broadcast of our members was actually notified
discordbot.py
import requests
import os.path
import re
import discord
import asyncio
from bs4 import BeautifulSoup
#Specify file path for notification management
listFilePath = 'list.txt'
#Replace with your bot's access token
TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
#Any channel ID(int)
CHANNEL_ID = 0000000000000000
#Set the community you want to check
targetCommunitys = ['co1520016']
#Returns True if there is a search in the list and False if there is none
def searchList(liveURL):
#File existence check
if not os.path.exists(listFilePath):
return False
liveLV = liveIdExtraction(liveURL)
#In-file check
with open(listFilePath) as f:
for i, line in enumerate(f):
if line == liveLV + '\n':
return True
print(line)
return False
#Add broadcast ID to the list
def addList(liveURL):
liveLV = liveIdExtraction(liveURL)
with open(listFilePath, 'a') as f:
print(liveLV, file=f)
#Broadcast ID from the broadcast URL(lvXXXXXXX)Extraction
def liveIdExtraction(liveURL):
repatter = re.compile('lv[0-9]+')
return repatter.search(liveURL).group()
#Get broadcast title from broadcast URL
def getLiveTitle(liveURL):
r = requests.get(liveURL)
soup = BeautifulSoup(r.content, "html.parser")
for meta_tag in soup.find_all('meta', attrs={'property': 'og:title'}):
return meta_tag.get('content')
#Obtaining the broadcaster name from the broadcast URL
def getLiveName(liveURL):
r = requests.get(liveURL)
soup = BeautifulSoup(r.content, "html.parser")
return soup.find("span",{"class":"name"}).text
#Generate the objects needed for the connection
client = discord.Client()
#Processing that operates at startup
@client.event
async def on_ready():
while(True):
#Repeat for the number of target communities
for targetCommunity in targetCommunitys:
#Set URL
r = requests.get("https://com.nicovideo.jp/community/" + targetCommunity)
#Check the community TOP page
soup = BeautifulSoup(r.content, "html.parser")
result = soup.find("section", "now_live")
#If the broadcast has started
if result is not None:
#Broadcast URL acquisition
liveURL = result.find("a", "now_live_inner").get("href")
#Search in the list and do not process if the broadcast ID has already been processed
if searchList(liveURL) is False:
#Broadcast title acquisition
liveTitle = getLiveTitle(liveURL)
#Broadcaster name acquisition
liveName = getLiveName(liveURL)
#Send to Discord
channel = client.get_channel(CHANNEL_ID)
await channel.send('@everyone ' + liveName + 'Has started delivery\n\n' + liveTitle + '\n' + liveURL)
#Broadcast ID postscript
addList(liveURL)
#Wait 1 minute
await asyncio.sleep(60)
#Connect to Discord
client.run(TOKEN)
--Scraping the community page of Nico Nico Live Broadcasting to get the broadcasting URL --Notify Discord --Leave the notified broadcast in a text file so that it will not be notified again
Specify the file name of the text file that leaves the broadcast once processed. as you like
discordbot.py
#Specify file path for notification management
listFilePath = 'list.txt'
Discord setting system
discordbot.py
#Replace with your bot's access token
TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
#Any channel ID(int)
CHANNEL_ID = 0000000000000000
Specify the community to be processed as an array. Supports multiple communities
discordbot.py
#Set the community you want to check
targetCommunitys = ['co1520016']
Determine if you have already been notified from the broadcast URL It is for checking to prevent notifying the same broadcast many times.
discordbot.py
#Returns True if there is a search in the list and False if there is none
def searchList(liveURL):
#File existence check
if not os.path.exists(listFilePath):
return False
liveLV = liveIdExtraction(liveURL)
#In-file check
with open(listFilePath) as f:
for i, line in enumerate(f):
if line == liveLV + '\n':
return True
print(line)
return False
Add the notified broadcast to the list
discordbot.py
#Add broadcast ID to the list
def addList(liveURL):
liveLV = liveIdExtraction(liveURL)
with open(listFilePath, 'a') as f:
print(liveLV, file=f)
Various data are obtained by scraping from the broadcast URL
discordbot.py
#Broadcast ID from the broadcast URL(lvXXXXXXX)Extraction
def liveIdExtraction(liveURL):
repatter = re.compile('lv[0-9]+')
return repatter.search(liveURL).group()
#Get broadcast title from broadcast URL
def getLiveTitle(liveURL):
r = requests.get(liveURL)
soup = BeautifulSoup(r.content, "html.parser")
for meta_tag in soup.find_all('meta', attrs={'property': 'og:title'}):
return meta_tag.get('content')
#Obtaining the broadcaster name from the broadcast URL
def getLiveName(liveURL):
r = requests.get(liveURL)
soup = BeautifulSoup(r.content, "html.parser")
return soup.find("span",{"class":"name"}).text
--I tried to actually run it on Heroku, but later I learned the specification that the local file is deleted every time it is restarted --Since the notification management file (list.txt) is deleted every time, there is a possibility that the same broadcast will be notified many times. -~~ It is necessary to have the data externally such as Google spreadsheet ~~ --Heroku seems to have a PostgreSQL database for free ――? ?? ?? "I didn't know that ..."
Recommended Posts