2011-01-18 13 views
13

Reddit.com web sitesine giriş yapmak, sayfanın belirli bir alanına gitmek ve bir yorum göndermek istiyorum. Bu kodda neyin yanlış olduğunu görmüyorum, ancak Reddit sitesine hiçbir değişiklik yansıtılmıyor.Form verisi göndermek ve kimlik bilgilerini doğrulamak için Python ve Mechanize kullanarak

import mechanize 
import cookielib 


def main(): 

#Browser 
br = mechanize.Browser() 


# Cookie Jar 
cj = cookielib.LWPCookieJar() 
br.set_cookiejar(cj) 

# Browser options 
br.set_handle_equiv(True) 
br.set_handle_gzip(True) 
br.set_handle_redirect(True) 
br.set_handle_referer(True) 
br.set_handle_robots(False) 

# Follows refresh 0 but not hangs on refresh > 0 
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1) 

#Opens the site to be navigated 
r= br.open('http://www.reddit.com') 
html = r.read() 

# Select the second (index one) form 
br.select_form(nr=1) 

# User credentials 
br.form['user'] = 'DUMMYUSERNAME' 
br.form['passwd'] = 'DUMMYPASSWORD' 

# Login 
br.submit() 

#Open up comment page 
r= br.open('http://www.reddit.com/r/PoopSandwiches/comments/f47f8/testing/') 
html = r.read() 

#Text box is the 8th form on the page (which, I believe, is the text area) 
br.select_form(nr=7) 

#Change 'text' value to a testing string 
br.form['text']= "this is an automated test" 

#Submit the information 
br.submit() 

Bunun nesi var?

+0

En az 10 saniye uyku eklemeye çalışın. Ayrıca, "Kaynağı Görüntüle" yi değil, Chrome'daki "Elementi Denetle" yi veya FF'de benzerlerini) tarayıcınızdaki formu incelemeniz ve indirilen HTML ile karşılaştırmanız gerekir. JS tarafından dinamik olarak doldurulmuş alanlara sahip olabilir. – TryPyPy

+1

Bu arada, Reddit'in bir API'si var, bu daha iyi çalışmaz mı? – TryPyPy

+0

Hmm, uyumaya çalışmama izin verin. Yorumlar göndermek için dokümantasyon olmadığı için API'yi nasıl kullanacağımı bilmiyorum. – Parseltongue

cevap

18

Kesinlikle mümkünse API kullanmaya çalışıyor öneririz, ama bu benim için çalışıyor (değil silinmiş senin örneğin yazı için, ancak herhangi bir aktif biri için):

#!/usr/bin/env python 

import mechanize 
import cookielib 
import urllib 
import logging 
import sys 

def main(): 

    br = mechanize.Browser() 
    cj = cookielib.LWPCookieJar() 
    br.set_cookiejar(cj) 

    br.set_handle_equiv(True) 
    br.set_handle_gzip(True) 
    br.set_handle_redirect(True) 
    br.set_handle_referer(True) 
    br.set_handle_robots(False) 

    br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1) 

    r= br.open('http://www.reddit.com') 

    # Select the second (index one) form 
    br.select_form(nr=1) 

    # User credentials 
    br.form['user'] = 'user' 
    br.form['passwd'] = 'passwd' 

    # Login 
    br.submit() 

    # Open up comment page 
    posting = 'http://www.reddit.com/r/PoopSandwiches/comments/f47f8/testing/' 
    rval = 'PoopSandwiches' 
    # you can get the rval in other ways, but this will work for testing 

    r = br.open(posting) 

    # You need the 'uh' value from the first form 
    br.select_form(nr=0) 
    uh = br.form['uh'] 

    br.select_form(nr=7) 
    thing_id = br.form['thing_id'] 
    id = '#' + br.form.attrs['id'] 
    # The id that gets posted is the form id with a '#' prepended. 

    data = {'uh':uh, 'thing_id':thing_id, 'id':id, 'renderstyle':'html', 'r':rval, 'text':"Your text here!"} 
    new_data_dict = dict((k, urllib.quote(v).replace('%20', '+')) for k, v in data.iteritems()) 

    # not sure if the replace needs to happen, I did it anyway 
    new_data = 'thing_id=%(thing_id)s&text=%(text)s&id=%(id)s&r=%(r)s&uh=%(uh)s&renderstyle=%(renderstyle)s' %(new_data_dict) 

    # not sure which of these headers are really needed, but it works with all 
    # of them, so why not just include them. 
    req = mechanize.Request('http://www.reddit.com/api/comment', new_data) 
    req.add_header('Referer', posting) 
    req.add_header('Accept', ' application/json, text/javascript, */*') 
    req.add_header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8') 
    req.add_header('X-Requested-With', 'XMLHttpRequest') 
    cj.add_cookie_header(req) 
    res = mechanize.urlopen(req) 

main() 

O olurdu Javascript'i kapatmak ve reddit yorumlarının nasıl ele alındığını görmek ilginç. Şu anda, postanızı oluştururken çağrılan bir onsubmit işlevinde gerçekleşen bir grup magic var. Bu, uh ve id değerinin eklendiği yerdir.

+0

Vay. Çok teşekkür ederim. Bunu asla anlayamazdım. – Parseltongue

+0

Hmm ... Bu hatayı, tüm aktif konular üzerinde alıyorum: ControlNotFoundError: 'thing_id.' Herhangi bir fikir? – Parseltongue

+0

Haha, no. Bu cümleyi yanlış yorumladınız - hangi programda aktif olarak kullandığım önemli değil, hala hatayı tetikliyor. Yapmaya çalıştığım program kendi amaçlarım için. Ilgili kitap bölümlerini I özel alt altditlerine gönderir. – Parseltongue

İlgili konular