初试Scrapy(三)上---CSDN自动登录获取博客分类列表

来源:互联网 发布:小米5关闭miui优化 编辑:程序博客网 时间:2024/04/28 10:35

初试Scrapy(三)上—CSDN自动登录获取博客分类列表

上一篇文章中初试Scrapy(二)—抓取豆瓣电影排行TOP250实验,通过Scrapy框架简单实现了一个豆瓣TOP250电影排行的小例子,这篇文章来学习下Scrapy框架下创建工程,同样我们给自己定一个小目标—实现CSDN自动登录,并且获取博客分类列表。为了不至于文章太长,这篇文章我打算分上下两篇,上篇主要是记录下不通过Scrapy框架实现CSDN自动登录获取博客分类列表,下篇文章中将完整的解释Scrapy创建文件的过程,并且对比实现CSDN自动登录获取博客分类列表功能。
废话不多说,直接上第一部分不通过Scrapy框架实现的代码:

# -*- coding: utf-8 -*-from fake_useragent import UserAgentimport urllibimport urllib2import cookielibimport reclass CsdnAutoLogin(object):    def __init__(self, username, password):        self.url = 'http://passport.csdn.net/account/login'        self.username = username        self.password = password        self.error_info = ''        self.login_status = 0        # the redirect url , after login succeed        self.redirect = ''        self.opener = CsdnAutoLogin.create_cookie()    @staticmethod    def create_cookie():        # '创建cookie'        cookie = cookielib.CookieJar()        cookie_proc = urllib2.HTTPCookieProcessor(cookie)        return urllib2.build_opener(cookie_proc)    def get_key_before_login(self):        # '在登录之前获取随机key'        html = self.opener.open(self.url).read().decode("utf8")        patten1 = re.compile(r'name="lt" value="(.*?)"')        patten2 = re.compile(r'name="execution" value="(.*?)"')        lt = patten1.search(html)        execution = patten2.search(html)        return {'lt': lt.group(1), 'execution': execution.group(1)}    @property    def login(self):        # '登录csdn'        response = None        # for random useragent        ua = UserAgent()        res = self.get_key_before_login()        opener = self.opener        post_data = {            'username': self.username,            'password': self.password,            'lt': res['lt'],            'execution': res['execution'],            '_eventId': 'submit',        }        opener.addheaders = [('host', 'passport.csdn.net'),                             ('User-Agent', ua.random),                             ('Referer', 'http://passport.csdn.net/account/login')                             ]        post_data = urllib.urlencode(post_data).encode(encoding='UTF8')        try:            response = opener.open(self.url, data=post_data)        except urllib2.URLError, err:            print(err)        finally:            # HTTP Error 500: Internal Server Error            if response is None:                self.login_status = 0                self.redirect = ''                self.error_info = u'服务器错误 HTTP Error 500: Internal Server Error'                raise Exception(self.error_info)            else:                text = response.read().decode('utf-8', 'ignore')                pattenerror = u'<span id="error-message">帐户名或登录密码不正确'                error = re.search(pattenerror, text)                if error is None:                    self.login_status = 1                    patten = re.compile(r'var redirect = "(.*?)"')                    self.redirect = patten.search(text).group(1)                else:                    self.login_status = 0                    self.redirect = ''                    self.error_info = u'帐户名或登录密码不正确'                    raise Exception(self.error_info)    def visit_redirect_after_login(self, redirect):        # '在登录之后访问跳转'        opener = self.opener        response = opener.open(redirect)        # text = response.read().decode('utf-8', 'ignore')        # tools.log(text, 'csdn_test.html')        response.read().decode('utf-8', 'ignore')    def visit_blog_category(self):        # '访问博客分类'        opener = self.opener        response = opener.open('http://write.blog.csdn.net/category')        text = response.read().decode('utf-8', 'ignore')        return CsdnAutoLogin.handle_blog_category(text)    @staticmethod    def handle_blog_category(text):        # '处理博客分类'        pattern = r"<td class='tdleft'><span>(.*?)</span></td>([\s\S]*?)<a href='#([0-9]+)'"        matchs = re.findall(pattern, text)        res = []        if matchs:            for i in matchs:                res.append({'name': i[0], 'id': i[2]})        return res    def add_blog_category(self, name):        # '添加博客分类,返回博客分类列表'        opener = self.opener        name = name.encode('utf-8', 'ignore')        name = urllib.quote(name)        url = 'http://write.blog.csdn.net/category?t=add&name=%s' % name        response = opener.open(url)        text = response.read().decode('utf-8', 'ignore')        return CsdnAutoLogin.handle_blog_category(text)    def edit_blog_category(self, blog_id, name):        # '修改博客分类名称'        opener = self.opener        name = name.encode('utf-8', 'ignore')        name = urllib.quote(name)        url = 'http://write.blog.csdn.net/category?t=edit&id=%s&name=%s' % (blog_id, name)        response = opener.open(url)        text = response.read().decode('utf-8', 'ignore')        return CsdnAutoLogin.handle_blog_category(text)    def main(self):        # '主方法'        try:            self.login        except Exception, err:            print(err.message)        finally:            if self.login_status == 1:                # print(self.redirect)                categorys = self.visit_blog_category()                for i in categorys:                    print(i['name'].encode("UTF-8"))if __name__ == '__main__':    csdn = CsdnAutoLogin('aaaaaaaaaaa', 'bbbbbbbbb')    csdn.main()

我的Python版本是:Python 2.7.5代码参考网上一哥们实现的,修改然后测试通过。下面是在pycharm上运行的输出:

/usr/bin/python2.7 /home/james_xie/PycharmProjects/Csdn_AutoLogin/csdn_autologin.pyC/C++学习Gstreamer学习Qt 学习计算机网络通信交叉编译环境的建立shell脚本学习Android学习Python学习Process finished with exit code 0

由于程序大体上都是参考前人的,总体上没遇到什么难题,不过还是有几个问题折腾了一会:
1, user-agent问题,在网上https://pypi.python.org/pypi/fake-useragent找到这样一个库,完美解决之,但是第一次运行的时候会有点慢,因为这个库会在会在第一次运行的时候收集当前所有可用的user-agent保存到你的操作系统的临时目录下面如:/tmp。
2, 服务器返回“HTTP Error 500: Internal Server Error”错误,没有找到很好的解决办法,网上有遇到类似问题多说是服务器那边问题,通过上面加载fake-useragent库之后,这个问题几乎很少再出现,然后通过添加try...except语句来对这个问题进行捕捉,后面就没更深入的研究。

1 0
原创粉丝点击