Cum să extrageți o listă de postări reddit salvate într-un fișier txt folosind praw în Python (Programare, Python, Web Scraping, Reddit, Praw)

gaxar a intrebat.
a intrebat.

Încerc un scraper simplu pentru a arunca postările Reddit salvate într-un fișier txt și mă lupt să fac scriptul să facă ceea ce vreau să facă.

Iată câteva contexte. Scriptul de mai jos descarcă toate ID-urile posturilor mele salvate într-un fișier text, fiecare în propria linie.

import praw
import os
import sys

reddit = praw.Reddit(client_id='MY_CLIENT_id',
                     client_secret='TOP_SECRET',
                     user_agent='AGENT_HERE',
                     username='USERNAME',
                     password='PASSWORD')

#open text file
sys.stdout = open('test.txt', 'w')
# get user saved item ids
for item in reddit.user.me().saved(limit=None):
    print(item.id)
# print to file
sys.stdout.close()

Acest lucru îmi oferă o listă de IDS-uri de post care arată cam așa:

lkj34f
ou456d
ho34oo
5j0vr4

Apoi, pot folosi scriptul de mai jos pentru a folosi fiecare dintre aceste ID-uri pentru a obține conținutul real pe care îl doresc

submission = reddit.submission(id="dg23y6")
print(submission.title)
print(submission.url)

Prima mea întrebare este – există o modalitate de a deschide fișierul de ieșire, de a citi fiecare dintre liniile de acolo și de a le trece ca id pentru variabila de trimitere?

Sunt sigur că există o modalitate mai ușoară de a obține acest lucru, desigur, am văzut mai multe scripturi existente de acest gen care aruncă tot conținutul într-un fișier HTML frumos format, dar nu sunt încă acolo, așa că încerc să rezolv această provocare folosind setul meu de abilități oarecum limitate. Cred că soluția cea mai evidentă ar fi să folosiți print(actual.command.I.am.missing) în loc de print(item.id), dar nu am nicio idee cum să o găsesc.

Mulțumesc în avans!

3 răspunsuri
jarhill0

Ambele răspunsuri care au fost trimise până acum au ideea corectă, dar fac o greșeală în modul în care folosesc PRAW. Ele ignoră faptul că elementele salvate sunt atât comentarii cât și postări. Apoi, ambele au o linie de genul

submission = reddit.submission(id=item.id)

Acest lucru creează un PRAW Submission utilizând ID-ul unui obiect preexistent, care este fie un obiect Submission fie un Comment obiect. În cazul în care este un Submission, noul Submission este identic cu cel din care este creat, deci este redundant. În cazul în care este un Comment, comportamentul este incorect deoarece tratați un ID de comentariu ca și cum ar fi un ID de trimitere.

Nu este clar ce anume doriți să se întâmple cu comentariile, așa că voi proceda în două moduri. În primul rând, iată cum să procedați dacă doriți să ignorați comentariile salvate (care seamănă mult cu răspunsurile existente, dar cu o verificare a tipului adăugată și cu linia redundantă eliminată):

import praw
import os
import sys

reddit = praw.Reddit(client_id='MY_CLIENT_id',
                     client_secret='TOP_SECRET',
                     user_agent='AGENT_HERE',
                     username='USERNAME',
                     password='PASSWORD')

with open('test.txt', 'w') as f:
    for item in reddit.user.me().saved(limit=None):
        if isinstance(item, reddit.models.Submission):
            f.write(item.id + '
')
            f.write(item.title + '
')
            if item.is_self:
                f.write(item.selftext + '
')
            else: # link post
                f.write(item.url)

Și iată cum se face în cazul în care, de asemenea, salvați comentarii:

import praw
import os
import sys

reddit = praw.Reddit(client_id='MY_CLIENT_id',
                     client_secret='TOP_SECRET',
                     user_agent='AGENT_HERE',
                     username='USERNAME',
                     password='PASSWORD')

with open('test.txt', 'w') as f:
    for item in reddit.user.me().saved(limit=None):
        if isinstance(item, reddit.models.Submission):
            f.write(item.id + '
')
            f.write(item.title + '
')
            if item.is_self:
                f.write(item.selftext + '
')
            else: # link post
                f.write(item.url)
        else: # comment
            f.write(item.id + '
')
            f.write(item.body + '
')

Comentarii

  • Îmi cer scuze că nu am clarificat scopul inițial aici. Recunosc că a fost în principal pentru că nu aveam habar că trebuie să fac diferența între cele două inițial, deși acum pare destul de evident 🙂 Oricum, cel de-al doilea script este exact ceea ce am vrut să fac, cu o mică precizare – a trebuit să comentez f.write(submission.url) pentru că nu era definită trimiterea și dădea o eroare. Fără ea funcționează exact așa cum am vrut. Vă mulțumesc! O să lucrez la partea de trimitere, toată documentația pe care am găsit-o arată că se face similar cu linia pe care ai indicat-o, nu un obiect generic de trimitere –  > Por gaxar.
  • Greșeala mea. submission.url ar trebui să fie item.url. –  > Por jarhill0.
Craicerjack

În loc să redeschideți fișierul, scrieți ce doriți în el atunci când este deschis

import praw
import os
import sys

reddit = praw.Reddit(client_id='MY_CLIENT_id',
                 client_secret='TOP_SECRET',
                 user_agent='AGENT_HERE',
                 username='USERNAME',
                 password='PASSWORD')
out_filename = 'test.txt'

with open(out_filename, 'w') as out_file:
    for item in reddit.user.me().saved(limit=None):
        out_file.write(item.id + '
')
        submission = reddit.submission(id=item.id)
        out_file.write(submission.title + '
')
        out_file.write(submission.url + '
')
        # or combine title and url on same line like this
        # out_file.write(submission.title + ': ' + submission.url + '
') 

Comentarii

  • Mulțumesc pentru răspuns, așa cum am menționat în răspunsul lui AKX, acest lucru mă apropie, dar nu chiar acolo. În timp ce îl rulează, primesc eroarea 404 HTTP Response, care, după un pic de googling, sugerează că scriptul încearcă să folosească ID-ul în mod incorect, prin urmare, aruncă eroarea. Utilizarea id=item.id este exact ceea ce căutam, așa că mai caut puțin pe Google, sper că nu mai sunt departe acum! –  > Por gaxar.
  • Eroarea 404 înseamnă că ceea ce căutați nu mai există. Ar trebui să verificați id-ul postului care aruncă eroarea și să vedeți dacă acel post mai există. –  > Por Craicerjack.
  • Cred că problema era inițial că eu căutam o trimitere și în schimb era un comentariu acolo. –  > Por gaxar.
AKX

În general, nu este o formă bună de a realoca sys.stdout. În schimb, puteți folosi print(..., file=...).

Îmi imaginez că ați putea căuta ceva de genul

import praw
import os
import sys

reddit = praw.Reddit(...)

with open("test.txt", "w") as f:
    for item in reddit.user.me().saved(limit=None):
        print(item.id)  # printed to the console
        item = reddit.submission(id=item.id)
        print(item.title, file=f)  # written to the file
        print(item.url, file=f)  # written to the file
        print('----', file=f)  # A separator, written to the file

Comentarii

  • Vă mulțumim că v-ați făcut timp să răspundeți. Acesta este, în principiu, ceea ce vreau să realizez, iar ambele răspunsuri, al tău și al lui Craicerjack, mă apropie, dar nu sunt chiar acolo. La rularea acestui script primesc următoarea eroare – print(submission.title, file=f) # scris în fișier NameError: name ‘submission’ is not defined. Este ceva ce am mai lovit înainte din păcate și redenumirea articolului în submission nu pare să rezolve problema. Totuși, utilizarea id=item.id este exact ceea ce căutam. –  > Por gaxar.
  • Greșeală de tipar fixată. Am vrut să reatribuiți înapoi la item, nu submission. –  > Por AKX.
  • De asemenea, dacă primiți erori 404, s-ar putea ca unele dintre elementele salvate să fi fost șterse între timp sau ar putea fi comentarii (caz în care reddit.submission() nu ar fi corect). Puteți să înfășurați un try: ... catch: ... în jurul lucrurilor pentru a le prinde pe cele problematice! –  > Por AKX.
  • Ah, asta explică multe, eu salvez atât comentariile, cât și trimiterile, acum înțeleg de ce uneori primesc o listă de două, trei ID-uri urmate de o eroare. Am mai învățat câte ceva 🙂 –  > Por gaxar.