2011-01-18 16 views
13

प्रमाणित करें मैं Reddit.com वेबसाइट पर लॉगिन जमा करना चाहता हूं, पृष्ठ के किसी विशेष क्षेत्र पर नेविगेट करना चाहता हूं, और एक टिप्पणी सबमिट कर सकता हूं। मुझे नहीं लगता कि इस कोड के साथ क्या गलत है, लेकिन यह काम नहीं कर रहा है कि Reddit साइट पर कोई बदलाव दिखाई नहीं देता है।फॉर्म डेटा जमा करने के लिए पायथन और मैकेनाइज का उपयोग करना और

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() 

इसमें क्या गलत है?

+0

कम से कम 10 सेकंड की नींद जोड़ने का प्रयास करें। आपको अपने ब्राउज़र में फॉर्म और डाउनलोड किए गए एचटीएमएल की तुलना में (स्रोत देखें 'नहीं, बल्कि क्रोम में' तत्व का निरीक्षण करें 'या एफएफ में समान) का निरीक्षण करना चाहिए। इसमें जेएस द्वारा गतिशील रूप से भरे फ़ील्ड हो सकते हैं। – TryPyPy

+1

वैसे, रेडडिट में एक एपीआई है, क्या यह बेहतर काम नहीं करेगा? – TryPyPy

+0

हम्म, मुझे नींद जोड़ने की कोशिश करें। मुझे यकीन नहीं है कि एपीआई का उपयोग कैसे करें क्योंकि टिप्पणियां जमा करने के लिए कोई दस्तावेज नहीं है। – Parseltongue

उत्तर

18

मैं निश्चित रूप से यदि संभव हो तो एपीआई का उपयोग करने की कोशिश कर रहा होगा की सलाह देते हैं, लेकिन यह मेरे लिए काम करता है (आपके उदाहरण पोस्ट है, जो हटा दिया गया है के लिए नहीं है, लेकिन किसी भी सक्रिय एक के लिए):

#!/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() 

यह होगा जावास्क्रिप्ट को बंद करने के लिए दिलचस्प है और देखें कि reddit टिप्पणियां तब कैसे प्रबंधित की जाती हैं। अभी magic का एक गुच्छा है जो आपकी पोस्ट बनाते समय एक ऑनसबमिट फ़ंक्शन में होता है। यह वह जगह है जहां uh और id मान जोड़ा गया।

+0

वाह। बहुत बहुत धन्यवाद। मैंने कभी यह नहीं सोचा होगा। – Parseltongue

+0

हम्म ... मुझे यह त्रुटि सभी सक्रिय धागे पर मिल रही है: ControlNotFoundError: कोई नियंत्रण मिलान नाम 'thing_id।' कोई विचार? – Parseltongue

+0

हाहा, नहीं। आपने उस वाक्य का गलत व्याख्या किया - इससे कोई फर्क नहीं पड़ता कि मैं इस प्रोग्राम का उपयोग किस सक्रिय धागे पर करता हूं, यह अभी भी त्रुटि को ट्रिगर करता है। जिस कार्यक्रम को मैं बनाने की कोशिश कर रहा हूं वह मेरे अपने उद्देश्यों के लिए है। यह प्रासंगिक पुस्तक अध्यायों को एक निजी subreddit I मध्यम करने के लिए पोस्ट करता है। – Parseltongue

संबंधित मुद्दे