您的位置:首页 > 编程语言 > Python开发

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

2016-12-21 17:17 501 查看

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

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

废话不多说,直接上第一部分不通过Scrapy框架实现的代码:

# -*- coding: utf-8 -*-
from fake_useragent import UserAgent
import urllib
import urllib2
import cookielib
import re

class 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.py
C/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
语句来对这个问题进行捕捉,后面就没更深入的研究。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息