Bonjour, c'est HanBei.
L'article précédent portait sur la collecte de données pour l'apprentissage automatique, mais nous continuerons cette fois.
Continuez à utiliser Google Colaboratory.
Si vous êtes intéressé, veuillez ** commenter ** ou ** LGTM **!
J'utilise le site de recettes, mais ** "C'est beaucoup" **, ** "Le plat vraiment recommandé est-il délicieux? (Excusez-moi)" **, donc je vais trouver la recette que je veux.
** J'espère que cela sera utile pour ceux qui souhaitent obtenir des données pour l'apprentissage automatique en utilisant les données sur le Web **.
Le grattage est un ** crime ** si vous ne suivez pas correctement l'utilisation et le dosage.
"Je veux faire du grattage, alors ne t'inquiète pas!" Pour ceux qui sont optimistes ou inquiets, nous vous recommandons de lire au moins les deux articles ci-dessous.
miyabisun: "Ne posez pas de questions sur le site Q&R pour savoir comment gratter" nezuq: "Liste des précautions pour le scraping Web"
Cet article vous apprend à gratter, mais ** nous déclinons toute responsabilité **.
Pensez par vous-même et utilisez-le avec la bonne éthique.
Cookpad, Nadia, White Rice.com Il existe un site de recettes pour, mais cette fois, nous utiliserons ** Rakuten Recipe **.
Raison, ・ Il existe des données quantitatives telles que «Je veux répéter», «C'était facile» et «J'ai sauvé». ・ De nombreuses recettes
est.
Si vous n'avez pas créé de compte Google pour utiliser Google Colaboratory, créez-en un.
Comment créer un nouveau bloc-notes ...
De là, j'écrirai le contenu de l'implémentation.
Tout d'abord, importez la bibliothèque.
from bs4 import BeautifulSoup
from google.colab import drive
from google.colab import files
import urllib
import urllib.parse
import urllib.request as req
import csv
import random
import pandas as pd
import numpy as np
import time
import datetime
Décidez du nom du plat que vous souhaitez rechercher!
#Le nom du plat que vous souhaitez rechercher
food_name = 'curry'
Créez une fonction pour obtenir l'URL de la recette.
#Stocker l'url de chaque recette
recipe_url_lists = []
def GetRecipeURL(url):
res = req.urlopen(url)
soup = BeautifulSoup(res, 'html.parser')
#Sélectionnez une gamme de liste de recettes
recipe_text = str(soup.find_all('li', class_= 'clearfix'))
#Divisez le texte acquis ligne par ligne et enregistrez-le dans la liste
recipe_text_list = recipe_text.split('\n')
#Lisez la liste ligne par ligne et extrayez uniquement les lignes qui correspondent au nom du plat
for text in recipe_text_list:
#Obtenez l'URL de chaque recette
if 'a href="/recipe/' in text:
#Spécifiez une pièce spécifique et mettez-la dans l'url
recipe_url_id = text[16:27]
#Combiner l'URL
recipe_url_list = 'https://recipe.rakuten.co.jp/recipe/' + recipe_url_id + '/?l-id=recipe_list_detail_recipe'
#URL du magasin
recipe_url_lists.append(recipe_url_list)
#Obtenez le titre de chaque recette
if 'h3' in text:
print(text + ", " + recipe_url_list)
Vérifiez les recettes par ordre de popularité
#Nombre de pages que vous souhaitez rechercher
page_count = 2
#Encoder pour mettre le nom du plat dans l'URL
name_quote = urllib.parse.quote(food_name)
#Combiner les URL (une seule URL de page)
#Par ordre de popularité
base_url = 'https://recipe.rakuten.co.jp/search/' + name_quote
#Nouvelle commande d'arrivée
# base_url = 'https://recipe.rakuten.co.jp/search/' + name_quote + '/?s=0&v=0&t=2'
for num in range(page_count):
#Pour obtenir après une page spécifique
# num = num + 50
if num == 1:
#Combiner les URL (une seule URL de page)
GetRecipeURL(base_url)
if num > 1:
#Combiner les URL (URL à partir de la page 2)
#Par ordre de popularité
base_url_other = 'https://recipe.rakuten.co.jp/search/' + name_quote + '/' + str(num) + '/?s=4&v=0&t=2'
#Nouvelle commande d'arrivée
# base_url_other = 'https://recipe.rakuten.co.jp/search/' + name_quote + '/' + str(num) + '/?s=0&v=0&t=2'
GetRecipeURL(base_url_other)
#Appliquer la règle 1 seconde pour le scraping
time.sleep(1)
Après cela, le titre et l'URL de la recette seront affichés.
Vérifions le nombre de recettes obtenues ici!
#Nombre de recettes acquises
len(recipe_url_lists)
Une fois exécuté, 17 éléments sont affichés.
Ensuite, nous allons acquérir les données nécessaires à partir de chaque recette.
data_count = []
recipe_data_set = []
def SearchRecipeInfo(url, tag, id_name):
res = req.urlopen(url)
soup = BeautifulSoup(res, 'html.parser')
for all_text in soup.find_all(tag, id= id_name):
# ID
for text in all_text.find_all('p', class_= 'rcpId'):
recipe_id = text.get_text()[7:17]
#date de sortie
for text in all_text.find_all('p', class_= 'openDate'):
recipe_date = text.get_text()[4:14]
#c'était délicieux,C'était facile,J'ai pu enregistrer 3 types de timbres
for text in all_text.find_all('div', class_= 'stampHead'):
for tag in text.find_all('span', class_= 'stampCount'):
data_count.append(tag.get_text())
#J'ai fait le nombre de rapports
for text in all_text.find_all('div', class_= 'recipeRepoBox'):
for tag in text.find_all('h2'):
#Lorsque le nombre de rapports est de 0
if tag.find('span') == None:
report = str(0)
else:
for el in tag.find('span'):
report = el.replace('\n ', '').replace('Cas', '')
print("ID: " + recipe_id + ", DATE: " + recipe_date + ",Numéro fait: " + report +
",Je veux répéter: " + data_count[0] +
",C'était facile: " + data_count[1] +
",J'ai pu sauver: " + data_count[2]+
", url: " + url)
#Stocker pour écrire dans un fichier csv
recipe_data_set.append([recipe_id, recipe_date, data_count[0], data_count[1], data_count[2], report, url])
#Vider le tableau contenant le nombre de tampons
data_count.clear()
#Restrictions de grattage
time.sleep(1)
Ici, vérifiez les données acquises.
for num in range(len(recipe_url_lists)):
SearchRecipeInfo(recipe_url_lists[num], 'div', 'detailContents')
Lorsque vous l'exécutez, vous pouvez voir qu'il a été acquis correctement.
Créez une feuille de calcul sur Google Drive et exportez les données
#Montez le répertoire que vous souhaitez utiliser
drive.mount('/content/drive')
Sélectionnez n'importe quel dossier dans Google Drive et spécifiez le nom du fichier Veuillez préciser "○○○".
#Créez un dossier sur Google Drive et spécifiez la destination d'enregistrement
save_dir = "./drive/My Drive/Colab Notebooks/〇〇〇/"
#Sélectionnez un nom de fichier
data_name = '〇〇〇.csv'
#Enregistrer le fichier csv dans le dossier
data_dir = save_dir + data_name
#Ajouter un élément au fichier csv
with open(data_dir, 'w', newline='') as file:
writer = csv.writer(file, lineterminator='\n')
writer.writerow(['ID','Release Date','Repeat','Easy','Economy','Report','URL'])
for num in range(len(recipe_url_lists)):
writer.writerow(recipe_data_set[num])
#Enregistrez le fichier créé
with open(data_dir, 'r') as file:
sheet_info = file.read()
Lorsqu'il est exécuté, 〇〇〇.csv sera affiché dans le répertoire spécifié. Veuillez vous référer au contenu jusqu'à présent dans une simple diapositive.
Vérifiez la sortie du fichier csv par Pandas.
#Charger csv
rakuten_recipes = pd.read_csv(data_dir, encoding="UTF-8")
#Prêt à ajouter à la colonne
df = pd.DataFrame(rakuten_recipes)
df
L'image de sortie est omise.
Ensuite, calculez le nombre de jours écoulés entre la date de publication de la recette et aujourd'hui.
# rakuten_recipes.Extraire la date de sortie de csv
date = np.array(rakuten_recipes['Release Date'])
#Obtenez la date actuelle
today = datetime.date.today()
#Faites correspondre le moule
df['Release Date'] = pd.to_datetime(df['Release Date'], format='%Y-%m-%d')
today = pd.to_datetime(today, format='%Y-%m-%d')
df['Elapsed Days'] = today - df['Release Date']
#Je ne retirerai que la valeur du nombre de jours écoulés
for num in range(len(df['Elapsed Days'])):
df['Elapsed Days'][num] = df['Elapsed Days'][num].days
#Ne cochez que 5 lignes du haut
df.head()
Ensuite, le nombre de jours écoulés apparaîtra à côté de la colonne URL.
Ensuite, laissez le nombre de jours écoulés être ** poids ** et pesez les trois types de timbres: répétition, facile et économique. Ajoutez les données pondérées à la colonne de recette existante.
#Fixé pour ne pas être trop petit
weighting = 1000000
#Extraire 3 types de tampons et rapporter les valeurs
repeat_stamp = np.array(rakuten_recipes['Repeat'])
easy_stamp = np.array(rakuten_recipes['Easy'])
economy_stamp = np.array(rakuten_recipes['Economy'])
report_stamp = np.array(rakuten_recipes['Report'])
#Total de chaque timbre et rapport
repeat_stamp_sum = sum(repeat_stamp)
easy_stamp_sum = sum(easy_stamp)
economy_stamp_sum = sum(economy_stamp)
report_stamp_sum = sum(report_stamp)
#Ajout d'une colonne de valeurs pondérées
'''
Répéter la pondération= (Nombre de tampons répétés ÷ répétition totale) × (Valeur corrigée ÷ nombre de jours écoulés depuis la date de publication)
'''
df['Repeat WT'] = (df['Repeat'] / repeat_stamp_sum) * (weighting / df['Elapsed Days'])
df['Easy WT'] = (df['Easy'] / easy_stamp_sum) * (weighting / df['Elapsed Days'])
df['Economy WT'] = (df['Economy'] / economy_stamp_sum) * (weighting / df['Elapsed Days'])
#Importance du rapport (plage de 0 à 1)
proportions_rate = 0.5
#Ajout d'une colonne de valeurs pondérées
'''
Répéter la pondération= (Répéter la pondération× (1 -importance)) × ((Nombre de rapports ÷ nombre total de rapports) ×importance[%])
'''
df['Repeat WT'] = (df['Repeat WT'] * (1 - proportions_rate)) * ((df['Report'] / report_stamp_sum) * proportions_rate)
df['Easy WT'] = (df['Easy WT'] * (1 - proportions_rate)) * ((df['Easy WT'] / report_stamp_sum) * proportions_rate)
df['Economy WT'] = (df['Economy WT'] * (1 - proportions_rate)) * ((df['Economy WT'] / report_stamp_sum) * proportions_rate)
À propos de la pondération ... Concernant le nombre de jours écoulés, supposons qu'il y ait des articles il y a un mois et il y a un an, et les mêmes 100 timbres sont attachés. Lequel est le plus recommandé pour la recette il y a un mois. Par conséquent, le score est inférieur pour les articles qui ont dépassé le nombre de jours.
Modifiez la plage des valeurs maximum et minimum des valeurs pondérées de 0 à 1. Je publierai la page que j'ai utilisée comme référence.
QUANON: "Convertir un nombre d'une plage en un nombre d'une autre plage"
df['Repeat WT'] = (df['Repeat WT'] - np.min(df['Repeat WT'])) / (np.max(df['Repeat WT']) - np.min(df['Repeat WT']))
df['Easy WT'] = (df['Easy WT'] - np.min(df['Easy WT'])) / (np.max(df['Easy WT']) - np.min(df['Easy WT']))
df['Economy WT'] = (df['Economy WT'] - np.min(df['Economy WT'])) / (np.max(df['Economy WT']) - np.min(df['Economy WT']))
df.head()
C'est le résultat de l'exécution. En faisant df.head (), seules les 5 premières lignes seront affichées.
Le score obtenu par l'utilisateur est évalué sur une échelle de 5 points et la recherche est effectuée.
#Utilisé pour spécifier la plage (1: 0-0.2, 2: 0.2-0.4, 3: 0.4-0.6, 4: 0.6-0.8, 5: 0.8-1)
condition_num = 0.2
def PlugInScore(repeat, easy, economy):
#Argument dans la plage spécifiée
if 1 >= repeat:
repeat = 1
if 5 <=repeat:
repeat = 5
if 1 >= easy:
easy = 1
if 5 <= easy:
easy = 5
if 1 >= economy:
economy = 1
if 5 <= economy:
economy = 5
#Affinez les recettes à partir de 3 types de partitions
df_result = df[((repeat*condition_num) - condition_num <= df['Repeat WT']) & (repeat*condition_num >= df['Repeat WT']) &
((easy*condition_num) - condition_num <= df['Easy WT']) & (easy*condition_num >= df['Easy WT']) &
((economy*condition_num) - condition_num <= df['Economy WT']) & (economy*condition_num >= df['Economy WT'])]
# print(df_result)
CsvOutput(df_result)
Exportez les résultats de la recherche dans un fichier csv. Veuillez saisir un nom pour 〇〇〇!
#Sélectionnez un nom de fichier
data_name = '〇〇〇_result.csv'
#Enregistrer le fichier csv dans le dossier
data_dir_result = save_dir + data_name
#Sortie csv
def CsvOutput(df_result):
#Afficher le résultat réduit dans un fichier csv
with open(data_dir_result, 'w', newline='') as file:
writer = csv.writer(file, lineterminator='\n')
#Titre
writer.writerow(df_result)
#Chaque valeur
for num in range(len(df_result)):
writer.writerow(df_result.values[num])
#Enregistrez le fichier créé
with open(data_dir, 'r') as file:
sheet_info = file.read()
AdviceRecipe()
Déclare une fonction pour afficher le résultat.
def AdviceRecipe():
#Charger csv
rakuten_recipes_result = pd.read_csv(data_dir_result, encoding="UTF-8")
#Prêt à ajouter à la colonne
df_recipes_res = pd.DataFrame(rakuten_recipes_result)
print(df_recipes_res)
print("Recommandé pour vous" + food_name + " 」")
print("Entry No.1: " + df_recipes_res['URL'][random.randint(0, len(df_recipes_res))])
print("Entry No.2: " + df_recipes_res['URL'][random.randint(0, len(df_recipes_res))])
print("Entry No.3: " + df_recipes_res['URL'][random.randint(0, len(df_recipes_res))])
Enfin, attribuez une note à la recette que vous souhaitez réaliser et affichez les recommandations.
'''
plug_in_score(repeat, easy, economy)Remplacer
repeat :Voulez-vous recommencer?
easy :Est-ce facile à faire?
economy:Pouvez-vous économiser de l'argent et le gagner?
Évaluez la subjectivité en 5 étapes de 1 à 5 et remplacez-la par un entier.
1 est négatif, 5 est la position
'''
PlugInScore(1,1,1)
3 types de points ** 1 **: Voulez-vous recommencer? ** 1 **: Est-ce facile à faire? ** 1 **: Pouvez-vous économiser de l'argent?
Le résultat de l'exécution est ...
・ Examen de la méthode d'évaluation Les trois valeurs pondérées sont tirées par la recette la plus élevée, ce qui donne des résultats extrêmes. Par conséquent, il est biaisé sur 1 ou 5.
・ Il y a peu d'articles estampillés Environ ** 10 **% des recettes ont des tampons et des rapports, et environ ** 90 **% de tous les 0 Par conséquent, il peut être absurde d'évaluer la recette par points. Il devrait y avoir une excellente recette dans All 0.
J'ai utilisé ce système pour rechercher "kimchi de porc" et j'ai essayé de le préparer. C'était délicieux car c'était une recette recommandée ^^
C'était intéressant car j'ai pu découvrir la recette qui était enterrée.
Merci à tous ceux qui ont lu jusqu'ici. Je vous serais reconnaissant de bien vouloir nous faire part de vos commentaires et conseils ^^
Recommended Posts