Python登录并获取CSDN博客所有文章列表代码实例


Posted in Python onDecember 28, 2017

分析登录过程

这几天研究百度登录和贴吧签到,这百度果然是互联网巨头,一个登录过程都弄得复杂无比,简直有毒。我研究了好几天仍然没搞明白。所以还是先挑一个软柿子捏捏,就选择CSDN了。

过程很简单,我也不截图了。直接打开浏览器,然后打开Fiddler,然后登录CSDN。然后Fiddler显示浏览器向https://passport.csdn.net/account/login?ref=toolbar发送了一个POST请求,这个请求包含了登录表单,而且还是未加密的。当然CSDN本身还是使用了HTTPS,所以安全性还行。

请求体如下,username和password当然是用户名和密码了。

username=XXXXX&password=XXXXXX&rememberMe=true<=LT-461600-wEKpWAqbfZoULXmFmDIulKPbL44hAu&execution=e4s1&_eventId=submit

lt参数我不知道是干啥的,结果直接在页面中一看原来全在表单里头,这下直接全了。CSDN很贴心的连注释都给出了。另外如果你打开百度首页的话,还会发现浏览器的log中还会输出百度的招聘信息。

Python登录并获取CSDN博客所有文章列表代码实例

HTML截图

登录代码

这些信息全有了,这样我们就可以登录了。不说废话,直接上代码。先说说我遇到的几个坑。

首先是一个参数错误,其实逻辑没问题,但是代码我复制粘贴之后忘了改名字了,就登录表单那里,三个参数全弄成了lt,结果登录返回来的页面是错误页面。我还以为是没有附带什么请求头,瞎整了大半天。最后用Fiddler调试了好多遍才发现。

第二个问题就是CSDN鸡贼的跳转。由于浏览器自带了JS引擎,所以我们在浏览器中输入网址,到达页面这一过程不一定就是一个请求。可能中间用了什么JS代码先跳转到中间页面,最后才跳转到实际页面。代码里的_validate_redirect_url(self)函数就是干这个的,登录完了第一次请求会得到一个中间页面,它包含了一堆JS代码,其中有个重定向网址。我们获取到这个重定向网址,还得请求一次,获得200OK之后,后续请求才能获得实际页面。

第三个问题就是正则表达式匹配页面的空格问题了。获取文章首先得知道文章总数,这个好办,直接获取页面里的文章数就行了。它类似100条共20页这个。那么该怎么获取呢?一开始我用的(\d+)条共(\d+)页这个正则,但是结果没匹配到,然后我仔细看了一下页面,原来这两个词之间不是一个空格,而是两个空格!其实这个问题倒是也好办,改一下正则(\d+)条\s*共(\d+)页就行了。所以以后如果遇到空格问题,直接用\s匹配,不要想着自己输入一个空格还是两个空格。

import requests
from bs4 import BeautifulSoup
import re
import urllib.parse as parse


class CsdnHelper:
  """登录CSDN和列出所有文章的类"""
  csdn_login_url = 'https://passport.csdn.net/account/login?ref=toolbar'
  headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
  }
  blog_url = 'http://write.blog.csdn.net/postlist/'

  def __init__(self):
    self._session = requests.session()
    self._session.headers = CsdnHelper.headers

  def login(self, username, password):
    '''登录主函数'''
    form_data = self._prepare_login_form_data(username, password)
    response = self._session.post(CsdnHelper.csdn_login_url, data=form_data)
    if 'UserNick' in response.cookies:
      nick = response.cookies['UserNick']
      print(parse.unquote(nick))
    else:
      raise Exception('登录失败')

  def _prepare_login_form_data(self, username, password):
    '''从页面获取参数,准备提交表单'''
    response = self._session.get(CsdnHelper.csdn_login_url)
    login_page = BeautifulSoup(response.text, 'lxml')
    login_form = login_page.find('form', id='fm1')

    lt = login_form.find('input', attrs={'name': 'lt'})['value']
    execution = login_form.find('input', attrs={'name': 'execution'})['value']
    eventId = login_form.find('input', attrs={'name': '_eventId'})['value']
    form = {
      'username': username,
      'password': password,
      'lt': lt,
      'execution': execution,
      '_eventId': eventId
    }

    return form

  def _get_blog_count(self):
    '''获取文章数和页数'''
    self._validate_redirect_url()
    response = self._session.get(CsdnHelper.blog_url)
    blog_page = BeautifulSoup(response.text, 'lxml')
    span = blog_page.find('div', class_='page_nav').span
    print(span.string)
    pattern = re.compile(r'(\d+)条\s*共(\d+)页')
    result = pattern.findall(span.string)
    blog_count = int(result[0][0])
    page_count = int(result[0][1])
    return (blog_count, page_count)

  def _validate_redirect_url(self):
    '''验证重定向网页'''
    response = self._session.get(CsdnHelper.blog_url)
    redirect_url = re.findall(r'var redirect = "(\S+)";', response.text)[0]
    self._session.get(redirect_url)

  def print_blogs(self):
    '''输出文章信息'''
    blog_count, page_count = self._get_blog_count()
    for index in range(1, page_count + 1):
      url = f'http://write.blog.csdn.net/postlist/0/0/enabled/{index}'
      response = self._session.get(url)
      page = BeautifulSoup(response.text, 'lxml')
      links = page.find_all('a', href=re.compile(r'http://blog.csdn.net/u011054333/article/details/(\d+)'))
      print(f'----------第{index}页----------')
      for link in links:
        blog_name = link.string
        blog_url = link['href']
        print(f'文章名称:《{blog_name}》 文章链接:{blog_url}')


if __name__ == '__main__':
  csdn_helper = CsdnHelper()
  username = input("请输入用户名")
  password = input("请输入密码")
  csdn_helper.login(username, password)
  csdn_helper.print_blogs()

当然,这里最重要的的就是登录过程了。我们登录之后,才可以做其他事情。比方说,下一步还能写一个备份工具,把CSDN博客的所有文章和图片下载到本地。有兴趣的同学可以试一试。

总结

以上就是本文关于Python登录并获取CSDN博客所有文章列表代码实例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

Python 相关文章推荐
Django与遗留的数据库整合的方法指南
Jul 24 Python
python多线程之事件Event的使用详解
Apr 27 Python
Django + Uwsgi + Nginx 实现生产环境部署的方法
Jun 20 Python
tensorflow 加载部分变量的实例讲解
Jul 27 Python
Python django使用多进程连接mysql错误的解决方法
Oct 08 Python
python使用socket 先读取长度,在读取报文内容示例
Sep 26 Python
将python包发布到PyPI和制作whl文件方式
Dec 25 Python
python GUI库图形界面开发之PyQt5多行文本框控件QTextEdit详细使用方法实例
Feb 28 Python
python获取响应某个字段值的3种实现方法
Apr 30 Python
Keras在训练期间可视化训练误差和测试误差实例
Jun 16 Python
如何解决pycharm调试报错的问题
Aug 06 Python
Anaconda安装pytorch和paddle的方法步骤
Apr 03 Python
python 寻找优化使成本函数最小的最优解的方法
Dec 28 #Python
python机器学习案例教程——K最近邻算法的实现
Dec 28 #Python
Python实现螺旋矩阵的填充算法示例
Dec 28 #Python
wxPython的安装图文教程(Windows)
Dec 28 #Python
Python制作豆瓣图片的爬虫
Dec 28 #Python
浅谈Python使用Bottle来提供一个简单的web服务
Dec 27 #Python
python编程实现12306的一个小爬虫实例
Dec 27 #Python
You might like
PHP操作Memcache实例介绍
2013/06/14 PHP
CI框架中libraries,helpers,hooks文件夹详细说明
2014/06/10 PHP
PHP常用技术文之文件操作和目录操作总结
2014/09/27 PHP
php表单敏感字符过滤类
2014/12/08 PHP
PHP时间戳格式全部汇总 (获取时间、时间戳)
2016/06/13 PHP
JAVASCRIPT keycode总结
2009/02/04 Javascript
jquery 插件学习(五)
2012/08/06 Javascript
javascript创建动态表单的方法
2015/07/25 Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
2015/11/15 Javascript
轻松学习jQuery插件EasyUI EasyUI表单验证
2015/12/01 Javascript
AngularJS入门教程之AngularJS指令
2016/04/18 Javascript
Node.js批量给图片加水印的方法
2016/11/15 Javascript
JS实现页面进入和返回定位到具体位置
2016/12/08 Javascript
JavaScript中${pageContext.request.contextPath}取值问题及解决方案
2016/12/08 Javascript
JS库之Waypoints的用法详解
2017/09/13 Javascript
javascript 作用于作用域链的详解
2017/09/27 Javascript
es6新特性之 class 基本用法解析
2018/05/05 Javascript
node.js 基于cheerio的爬虫工具的实现(需要登录权限的爬虫工具)
2019/04/10 Javascript
JS实现的检验身份证格式并输出出生日期,年龄,性别,出生地示例
2019/05/17 Javascript
Python yield 使用方法浅析
2017/05/20 Python
Python实现随机生成有效手机号码及身份证功能示例
2017/06/05 Python
Python语言生成水仙花数代码示例
2017/12/18 Python
python列表使用实现名字管理系统
2019/01/30 Python
Python文件操作函数用法实例详解
2019/12/24 Python
Pytest框架之fixture的详细使用教程
2020/04/07 Python
五个2015 年最佳HTML5 框架
2015/11/11 HTML / CSS
新西兰廉价汽车租赁:Snap Rentals
2018/09/14 全球购物
CHARLES & KEITH加拿大官网:新加坡时尚品牌
2020/03/26 全球购物
Super-Pharm波兰:药房和香水在一个地方
2020/08/18 全球购物
SQL Server数据库笔试题和答案
2016/02/04 面试题
自动化系在校本科生求职信
2013/10/23 职场文书
会议活动邀请函
2014/01/27 职场文书
我爱我的祖国演讲稿
2014/05/04 职场文书
2014旅游局领导班子四风问题对照检查材料思想汇报
2014/09/19 职场文书
Spring中bean集合注入的方法详解
2022/07/07 Java/Android
JS高级程序设计之class继承重点详解
2022/07/07 Javascript