1
votes

BeautifulSoup Find dans une page html instagram



4 commentaires

Avez-vous quelques exemples d'URL avec lesquels travailler?


Oui et non. Oui, toute page de publication de page qui contient plusieurs images (dans le style carrousel) mais les pages sont générées par intagram avec notre jeton d'utilisateur unique, donc je ne peux pas vraiment vous la transmettre telle quelle ... :(


Oui donc pour ça j'ai essayé d'ajouter une partie d'un code source ... ^^


saisir la balise de script appropriée et la regexer


3 Réponses :


1
votes

Vous pouvez trouver la balise de script appropriée et regexer les informations. J'ai supposé que la première balise de script contenant window._sharedData = est la bonne. Vous pouvez bricoler si nécessaire.

soup = bs(html, 'lxml')
r = re.compile(r'"display_url":(.*)",')
data = soup.find('script', text=r).text
print(r.findall(data))

Grâce à @thadam, il peut être possible de raccourcir ce qui précède en:

from bs4 import BeautifulSoup as bs
import re

html = '''
<html>
 <head></head>
 <body class=""> 
  <span id="react-root">
   <svg width="50" height="50" viewbox="0 0 50 50" style="position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;fill:#c7c7c7"> 
    <path d="

        <!––deleted part for privacy -->

         " /> 
   </svg></span> 
  <script type="text/javascript">
    window._sharedData = {
      "config": {
        "csrf_token": "",
        "viewer": {

        <!––deleted part for privacy -->

        "viewerId": ""
      },
      "supports_es6": true,
      "country_code": "FR",
      "language_code": "fr",
      "locale": "fr_FR",
      "entry_data": {
        "PostPage": [{
          "graphql": {
            "shortcode_media": {
              "__typename": "GraphSidecar",

     <!––deleted part for privacy -->

              "dimensions": {
                "height": 1080,
                "width": 1080
              },
              "gating_info": null,
              "media_preview": null,

<--There's the important part that have to be extracted as many times it appear in the source code-->

              "display_url": "https://scontent-cdt1-1.cdninstagram.com/vp/",
              "display_resources": [{
                "src": "https://scontent-cdt1-1.cdninstagram.com/vp/",
                "config_width": 640,
                "config_height": 640
              }, {
                "src": "https://scontent-cdt1-1.cdninstagram.com/vp/",
                "config_width": 750,
                "config_height": 750
              }, {
                "src": "https://scontent-cdt1-1.cdninstagram.com/vp/",
                "config_width": 1080,
                "config_height": 1080
              }],
              "is_video": false,</script>
 </body>
</html>
'''

soup = bs(html, 'lxml')
scripts = soup.select('script[type="text/javascript"]')
for script in scripts:
    if ' window._sharedData =' in script.text:
        data = script.text
        break
r = re.compile(r'"display_url":(.*)",')
print(r.findall(data))

p >


9 commentaires

Vous pouvez raccourcir votre code si vous utilisez votre regex comme paramètre text dans .find () , par exemple: data = soup.find ('script', text = r) .text


Vous êtes les bienvenus! Parfois, il est préférable d'utiliser .find () / .find_all () car ils acceptent les expressions régulières et les fonctions.


Salut. En essayant l'idée @thadam dans mon logiciel, le résultat est devenu: Fichier "main.py", ligne 27, dans soup = bs (soup1, 'lxml') Fichier "/home/runner/.site-packages /bs4/__init__.py ", ligne 244, dans init markup = markup.read () TypeError: l'objet 'NoneType' ne peut pas être appelé.


les données sont-elles chargées dynamiquement? imprimer la soupe et vérifier


Impossible de l'imprimer car: dans soup = bs (html, 'lxml') File "/ var / containers / Bundle / Application / 93F4D70C-FD37-45C8-80BD-‌ F48B0E2BCCB3 / Pythoni‌ sta3 .app / Frameworks / ‌ Py3Kit.framework / pyl‌ ib / site-packages / bs4‌ /__init__.py ", ligne 158, dans __init__%", ". join (features)) bs4.FeatureNotFound: Impossible de trouver un constructeur d'arbres avec les fonctionnalités que vous avez demandées: lxml Avez-vous besoin d'installer une bibliothèque d'analyseurs?


changer lxml pour html.parser


Pardon comment ce lien? J'utilise des requêtes


comment votre commentaire de code se rapporte-t-il à ma réponse s'il vous plaît?


Désolé j'ai pensé que c'était là pour expliquer l'avancement de mon projet mais j'ai corrigé ma faute avec la nouvelle réponse :( [donc j'ai supprimé mes faux commentaires]



0
votes

Le programme a avancé et il est devenu quelque chose comme ceci:

thepage = urllib.request.urlopen(html)
    soup = BeautifulSoup(thepage, "html.parser")
    print(soup.title.text)
    txt = soup.select('script[type="text/javascript"]')[3] 
    texte = txt.get_text()
    f1 = open("tet.txt", 'w')
    f1.write(texte)
    f1.close() 
    with open('tet.txt','r') as f:
        data=''.join(f.readlines())
    print(data[data.index('"display_url":"'):data.index('","display_resources":')+1])

Mais maintenant quelque chose de nouveau est apparu:

  • Comment faire en sorte que l'URL de recherche fasse partie du programme (lignes 10, 11) répéter tant que (' "display_url": " to -> " , "display_resources": ') apparaissent dans le fichier tet.txt ?
  • La boucle while peut être utilisée mais comment la faire répéter le processus?


0 commentaires

0
votes

Problème résolu

Voici le code pour télécharger plusieurs images à partir d'une url instagram avec Pythonista 3 sur iOS:

    from sys import argv
    import urllib
    import urllib.request
    from bs4 import BeautifulSoup 
    import re
    import photos
    import clipboard


    thepage = "your url"
#p.1
    thepage = urllib.request.urlopen(html)
    soup = BeautifulSoup(thepage, "html.parser")
    print(soup.title.text)
    txt = soup.select('script[type="text/javascript"]')[3] 
    texte = txt.get_text()
    fille = open("tet.txt", 'w')
    fille.write(texte)
    fille.close()
#p.2
    g = open('tet.txt','r')
    data=''.join(g.readlines())
    le1 = 0
    le2 = 0
    hturl = open('url.html', 'w')
    still_looking = True
    while still_looking:
        still_looking = False
        dat = data.find('play_url', le1)
        det = data.find('play_resources', le2)
        if dat >= le1:
            #urls.append(dat)
            le1 = dat + 1
            still_looking = True                
        if det >= le2:
            hturl.write(data[dat:det])
            le2 = det + 1
            still_looking = True
    hturl.close()
#p.3
    hturl2 = open('url.html', 'r')
    dete = ''.join(hturl2.readlines())
    le11 = 0
    le22 = 0
    urls = []
    still_looking2 = True
    while still_looking2:
        still_looking2 = False
        dat2 = dete.find('https://scontent-', le11)
        det2 = dete.find('","dis', le22)
        if dat2 >= le11:
            urls.append(dat2)
            le11 = dat2 + 1
            still_looking2 = True                
        if det2 >= le22:
            urls.append(dete[dat2:det2])
            le22 = det2 + 1
            still_looking2 = True   
    hturl2.close()
#p.4
    imgs = len(urls)
    nbind = imgs
    nbindr = 3 
    images = 1
    while nbindr < imgs:
        urllib.request.urlretrieve(urls[nbindr], 'photo.jpg')
        photos.create_image_asset('photo.jpg')
        print ('Image ' + str(images) + ' downloaded')
        nbindr = nbindr +2
        images += 1
    print("OK")

C'est un peu fastidieux mais cela fonctionne et rapidement aussi . Merci pour votre aide.


0 commentaires