Following all followers in NokNok
สคริปต์ noknok.py เมื่อวันก่อนทำเอาหลายคนกลายเป็นสแปม เพราะพยายามจะเอาไปรันใน cron ยกตัวอย่างเช่น @pruet คราวนี้เลยแก้ตัวใหม่ ใส่ไฟล์คอนฟิกให้อันนึง อย่างน้อยก็เอาไว้เก็บว่าเคย sync ถึงไหนแล้ว และแถมด้วยการติดตามเพื่อนทุกคนของคนที่ต้องการ
เนื่องจาก NokNok ยังไม่มี APIs ผมก็ขี้เกียจทำ regexp สุดท้ายเลยตัดสินใจใช้ XPath ของ lxml ซะเลย ดูเหมือนว่าจะไม่มี lxml บนวินโดส์ ยังไม่รู้จะแก้ปัญหาให้ยังไง คำแนะนำตอนนี้คือ ลงลินุกซ์
#!/usr/bin/env python # -*- encoding: utf-8 -*- from urllib import urlencode from urllib2 import urlopen, HTTPCookieProcessor, build_opener, install_opener, Request import re import os import getpass from optparse import OptionParser from ConfigParser import ConfigParser import simplejson cookie_processor = HTTPCookieProcessor() opener = build_opener(cookie_processor) install_opener(opener) user_agent = 'noknok' def confopt(conf, section, option, default=None): try: return conf.get(section, option) except: return default def user_timeline(u, since_id=0): url = 'http://twitter.com/statuses/user_timeline/%s.json' % u data = {} if since_id > 0: data['since_id'] = since_id req = Request(url, urlencode(data), {'User-Agent': user_agent}) fd = urlopen(req) results = simplejson.loads(fd.read()) return filter(lambda x: x['id'] > since_id, results) def summize(q, since_id=0): url = 'http://summize.com/search.json' req = Request(url, urlencode({'q': q, 'since_id': since_id}), {'User-Agent': user_agent}) fd = urlopen(req) results = simplejson.loads(fd.read())['results'] return results class NokNok: url = 'http://www.noknok.in.th/' def __init__(self, username, password): self.username = username self.password = password def home(self): url = self.url+'myhome' fd = urlopen(url) fd.read() def login(self): #print 'logging in' url = self.url+'login/' fd = urlopen(url, urlencode({'username': self.username, 'password': self.password, 'remember_me': '1'})) content = fd.read() if fd.code != 200: print code, content #print fd.headers #print content def post(self, msg): #print 'posting %s' % msg url = self.url+'message/add' req = Request(url, urlencode({'msg_update': msg.encode('utf-8')}), {'Referer': self.url+'myhome'}) fd = urlopen(req) content = fd.read() #print fd.headers #print content if fd.code != 200: print code, content def get_followers(self, user=None): from lxml import etree as ET user = user or self.username url = self.url+user+'/followers' followers = [] while 1: fd = urlopen(url) content = fd.read() tree = ET.HTML(content.decode('utf-8')) node = tree.xpath("//ul[@class='list_friends_follow']")[0] for item in node: d = {'screen_name': item.findtext('h3'), 'links': {}} links = item.xpath('./ul/li[3]/span/a') for i in links: title = i.attrib['title'] if title == u'ติดตาม': d['links']['follow'] = i.attrib['href'] elif title == u'บล็อค': d['links']['block'] = i.attrib['href'] followers.append(d) next = tree.xpath("//span[@class='next-page']")[0].find('a') if next is None: break url = next.attrib['href'] return followers def runonce(nok, q, query, since_id=0, cb_save=None): try: results = query(q, since_id=since_id) except Exception, why: print why results = [] results.reverse() for item in results: nok.post(item['text']) since_id = item['id'] if cb_save: cb_save(since_id) return since_id def run(nok, q, query, since_id=0, interval=30, cb_save=None): import time if since_id == 0: since_id = query(q)[0]['id'] while 1: since_id = runonce(nok, q, query, since_id, cb_save) time.sleep(interval) class App: def __init__(self): usage = '''usage: %prog [options] followall|twitteronce|twitterforever Commands: followall [screen_name] twitteronce twitterforever''' parser = OptionParser(usage=usage) parser.add_option('-c', '--config', default='noknok.cfg', dest='config', help='configuration file') self.options, self.args = parser.parse_args() def run(self): if len(self.args) > 0: command = self.args[0] else: command = 'twitterforever' method = getattr(self, 'do_%s' % self.args[0]) if not method: print 'unknown command' return self.conf = ConfigParser() self.conf.read([self.options.config, 'noknok.cfg', os.path.expanduser('~/.noknok.cfg')]) username = confopt(self.conf, 'noknok', 'username') if username is None: username = raw_input('noknok user: ') password = confopt(self.conf, 'noknok', 'password') if password is None: password = getpass.getpass('noknok password: ') self.nok = NokNok(username, password) self.nok.login() return method() def do_followall(self): if len(self.args) > 1: user = self.args[1] else: user = self.nok.username for user in self.nok.get_followers(user): if 'follow' in user['links']: print 'following %s' % user['screen_name'] fd = urlopen(user['links']['follow']) fd.read() def do_twitterforever(self): q = confopt(self.conf, 'twitter', 'query') if q is None: q = raw_input('twitter user: ') query = confopt(self.conf, 'twitter', 'source', 'user_timeline') since_id = int(confopt(self.conf, 'twitter', 'since_id', '0')) interval = int(confopt(self.conf, 'twitter', 'interval', '30')) run(self.nok, q, eval(query), since_id, interval, self._save_since_id) def do_twitteronce(self): q = confopt(self.conf, 'twitter', 'query') if q is None: q = raw_input('twitter user: ') query = confopt(self.conf, 'twitter', 'source', 'user_timeline') since_id = int(confopt(self.conf, 'twitter', 'since_id', '0')) runonce(self.nok, q, eval(query), since_id,self._save_since_id) def _save_since_id(self, since_id): self.conf.set('twitter', 'since_id', str(since_id)) self.conf.write(open(self.options.config, 'w')) if __name__ == '__main__': app = App() app.run()
ยาวขึ้นเยอะเหมือนกัน คราวนี้ฉลาดขึ้น ควรใช้ไฟล์คอนฟิกให้เป็นประโยชน์ด้วย หน้าตาประมาณนี้
[twitter] source = user_timeline since_id = 0 query = sugree [noknok] username = sugree password = xxxxxx
ถ้าอยากใช้ summize ก็แก้ตรง source วางไฟล์นี้ไว้ที่เดียวกับ noknok.py หรือจะไว้ที่ ~/.noknok.py ก็ด้ ตอนนี้มี 3 คำสั่ง
python noknok.py twitterforever
อันนี้ทำเหมือนรุ่นเก่า รันไปเรื่อย
python noknok.py twitteronce
จะอ่านรอบเดียว ส่งรอบเดียว
python noknok.py followall
ค้นหาว่าใครที่ติดตามเราแล้วเรายังไม่ได้ติดตามกลับ ก็ติดตามซะ
python noknok.py followall sugree
แบบนี้จะติดตามทุกคนที่ติดตาม sugree กรุณาใช้ด้วยความระวัง
เตือนแล้วนะ_
ว่าแล้วก็เตรียมทำ python-noknok ดีกว่า





Great work, my master.
Works like a charm on Cygwin (I mean, on Windows)
:)
ตั้งโต๊ะลง linux กันดีกว่า สร้าง factor ให้คนจำต้องใช้แบบนี้เยอะๆ แล้วก็นัดกัน ยกโน้ตบุ๊กมาหักดิบลง linux กันเลย
เอา mac มาลงก่อนเลย
T_T" copy ไปแปะเลยไม่ได้เหรอ? ลอง copy จากกล่องใหญ่ๆ แล้วมันเปิดไม่ได้.. (ประจำ.. ลองอะไรแล้วได้เรื่องประจำเลย)
อ๊าาาาาาาาาา ทำไม ทำไม
ถ้าอ่านแล้วทำตามได้เมื่อไหร่จะให้ประกาศนียบัตร
Work great on my hardy.
Post new comment