[PYTHON] Analysez la réponse pour pouvoir gratter la propre histoire de Wantedly

Préface

Nijibox utilise Wantedly pour le recrutement de carrière. (Si vous êtes intéressé par ici)

Donc, lorsque l'histoire a été mise à jour, je me suis demandé si je pouvais informer Slack dans l'entreprise, mais j'ai regardé la source, mais Le flux RSS n'existe pas. [^ 1] Quand il s'agit de cela, il devient nécessaire d'utiliser pleinement l'analyseur pour bien traiter la structure de données ...

Je vais laisser ce que j'ai fait pour cela dans cet article.

Début et objectif d'aujourd'hui

Le matériau est "l'histoire" de Wantedly of Nijibox. https://www.wantedly.com/companies/nijibox/feed

De là, j'écrirai le code pour extraire "une structure de données qui peut supporter une autre sortie".

Réponse (= produit fini)

feed-from-wantedly.py


import json
import pprint
import requests
from bs4 import BeautifulSoup

URL = 'https://www.wantedly.com/companies/nijibox/feed'

resp = requests.get(URL)
soup = BeautifulSoup(resp.content, 'html.parser')
# <script data-placeholder-key="wtd-ssr-placeholder">Je vais chercher le contenu
#Le contenu de cette balise est une chaîne de caractères JSON, mais au début'// 'Supprimé pour lecture car il y a
feed_raw = soup.find('script', {'data-placeholder-key': "wtd-ssr-placeholder"}).string[3:]
feeds = json.loads(feed_raw)
#Il y a différentes choses dans le corps dans l'ensemble du JSON, mais le corps lui-même est devenu une clé qui semble être une clé d'entreprise dans dict
#Cependant, il semble qu'il n'y en ait qu'un, donc il est extrait très grossièrement
feed_body = feeds['body'][list(feeds['body'].keys())[0]]

#Éléments qui semblent être des messages fixes
pprint.pprint(feed_body['latest_pinnable_posts'])

Lorsque vous faites cela, cela ressemble à ceci:

$ python3 feed-from-wantedly.py
[{'id': 188578,
  'image': {'id': 4141479,
            'url': 'https://d2v9k5u4v94ulw.cloudfront.net/assets/images/4141479/original/9064f3ba-9327-4fce-9724-c11bf1ea71e2?1569833471'},
  'post_path': '/companies/nijibox/post_articles/188578',
  'title': 'N'hésitez pas à commencer par une interview informelle! Ce que Nijibox veut transmettre aux demandeurs d'emploi, leurs réflexions sur l'embauche'},
 {'id': 185158,
  'image': {'id': 4063780,
            'url': 'https://d2v9k5u4v94ulw.cloudfront.net/assets/images/4063780/original/44109f75-6590-43cb-a631-cb8b719564d4?1567582305'},
  'post_path': '/companies/nijibox/post_articles/185158',
  'title': '[Pour les débutants] Le design n'est pas "sens" mais "théorie". Vous pouvez le faire dès aujourd'hui! Comment devenir un concepteur d'interface utilisateur'},
 {'id': 185123,
  'image': {'id': 4062946,
            'url': 'https://d2v9k5u4v94ulw.cloudfront.net/assets/images/4062946/original/ff2169c7-568e-4992-b082-56f1e1be2780?1567573415'},
  'post_path': '/companies/nijibox/post_articles/185123',
  'title': 'Nous avons eu une session d'étude React avec M. Ikeda de ICS!'}]

Préparation

Cette fois, je l'ai fait dans l'environnement suivant.

Regardez dans l'ordre

Jusqu'à ce que "Recevoir la réponse avec les demandes et l'analyser avec BeautifulSoup4", c'est ce qu'on appelle commun, donc je vais l'ignorer cette fois.

Où analyser plus

Cette fois, je vais trouver et analyser les "Articles en vedette", mais il y a environ deux problèmes ici.

Ce dernier est particulièrement gênant, et la méthode de poursuite des balises avec «soup.find» ne fonctionne pas. [^ 2]

Ensuite, où analyser スクリーンショット 2019-11-26 19.40.05.png

C'est ici.

Considération voulue de SSR (source uniquement)

スクリーンショット 2019-11-26 19.42.30.png

Ceci est le résultat d'une recherche Google pour "Nijibox" et "Wantedly" comme décrit ci-dessus, mais le contour etc. qui ne sont pas dans la balise "body" de la réponse est correctement répertorié. Le site de Wantedly semble avoir une spécification pour avoir le contenu lui-même en tant que matériau JSON au moment de l'exécution de JS et le rendre.

Extraire l'élément correspondant avec Beautiful Soup

C'est la seule ligne où «Beautiful Soup» fait son travail.

feed_raw = soup.find('script', {'data-placeholder-key': "wtd-ssr-placeholder"}).string[3:]

Find_all of Beautiful Soup est efficace non seulement pour les balises mais aussi pour le niveau d'attribut, vous pouvez donc obtenir le contenu que vous souhaitez prendre en une seule fois. C'est pratique. La raison de l'utilisation de string [3:] est qu'il y a un caractère obstructif au début du contenu, qui est // à analyser comme JSON. [^ 3]

Après cela, je pense que la chaîne de caractères JSON est transformée en objet et uniquement analysée ...

En gros, le contenu de l'objet analysé ressemble à ceci.

{
  "router":{"Abréviation"},
  "page":"companies#feed",
  "auth":{"Abréviation"},
  "body":{
    "c29bc423-7f81-41c2-8786-313d0998988c":{
      "company":{"Abréviation"}
    }
  }
}

Le mystérieux UUID. Peut-être quelque chose à utiliser séparément de l'ID de l'entreprise.

Nous devons donc approfondir ce contenu.

feed_body = feeds['body'][list(feeds['body'].keys())[0]]

Heureusement, il semble que la clé utilisée dans le contenu de body ne concerne qu'une seule entreprise, donc je vais la diviser très grossièrement dans le dos.

Enfin extraire des éléments

Pour l'instant, il y a deux éléments qui semblent utiles.

posts: Toutes les histoires jusqu'à présent? latest_pinnable_posts: La partie correspondant aux" Articles en vedette "

Cette fois, j'ai décidé que je n'avais besoin que du minimum, alors j'ai sorti latest_pinnable_posts et j'ai terminé. Je vous remercie pour votre travail acharné.

pprint.pprint(feed_body['latest_pinnable_posts'])

Qu'en est-il des notifications Slack?

Je ne l'ai pas encore fait pour le moment.

Il existe une approche comme celle-ci. Non applicable cette fois pour le moment.

Regarder en arrière

Cela fait un moment que je n'ai pas touché à Beautiful Soup4, mais après tout, il a toutes les fonctions et est facile à utiliser.

[^ 1]: Wantedly Il existe lorsque vous recherchez "application / rss + xml" en haut ou dans la source de la page de l'entreprise, mais il semble qu'il n'y ait rien de particulier dans ce contenu. [^ 2]: Bien sûr, vous pouvez exécuter JS avec un navigateur sans tête etc. et créer le DOM en fonction de la situation que le navigateur regarde, mais cette fois, il n'est pas adopté [^ 3]: je ne connais pas la raison [^ 4]: comme il n'y a pas de date et d'heure de publication dans les données qui peuvent être collectées, le goulot d'étranglement est que vous ne pouvez pas faire quelque chose comme "re-notifier une fois modifié"

Recommended Posts

Analysez la réponse pour pouvoir gratter la propre histoire de Wantedly
Pouvez-vous supprimer ce fichier?
Peut-être que vous pouvez gratter en utilisant Twitter Scraper
Jusqu'à ce que vous puissiez lire le journal des erreurs