Python爬取自己CSDN后台原始markdown数据

个人博客之类的项目基本上是每个程序员必做的项目了,一般博客完成之后,大家都希望将自己在其他博客系统(如CSDN)上的文章转移至自己的数据库中,如果自己以前的文章过多,一篇篇复制粘贴也太费时间了,这个时候我们可以选择爬虫的方式,将自己的文章爬下来。

如果爬取的是博客主页,爬下来的数据也还是HTML或者普通文本,到时候还要自己处理,最好的当然是爬取自己后台的原始markdown数据了。本文将介绍如何使用Python爬取CSDN后台原始的markdown数据

博主也是自学不久的爬虫,如有不对的地方希望大佬不吝赐教!

网页解析

我们进入CSDN的后台——内容管理,进入调试模式,打开一篇博客进行编辑,可以发现请求的接口如下:

在这里插入图片描述

并且从返回结果中可得如下信息:

在这里插入图片描述

其中markdowncontent即是我们的markdown源内容了。

按照基本的爬虫,知道接口、获取请求头这些也就可以开搞了,但是我们实践的时候就会发现,结果不是400就是403,很明显,我们设置的请求头有问题,经过反复验证,发现Request Headers里面有几个内容并非常量。

生成请求变量

在这里插入图片描述
以上四个内容,调试js发现x-ca-key 和 x-ca-signature-headers是一个常量,但是x-ca-nonce是每一次请求都需要从新生成的, 而 x-ca-signature 是一个经过x-ca-nonce和url结合的后加密后得到的,因此,我们要按照js的规则去自己生成这两个变量。

def createUuid():
    text = ""
    char_list = []
    for c in range(97,97+6):
        char_list.append(chr(c))
    for c in range(49,58):
        char_list.append(chr(c))
    for i in "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx":
        if i == "4":
            text += "4"
        elif i == "-":
            text += "-"
        else:
            text += random.choice(char_list)
    return text

def get_sign(uuid,url):
    s = urlparse(url)
    ekey = "9znpamsyl2c7cdrr9sas0le9vbc3r6ba".encode()
    to_enc = f"GET\n*/*\n\n\n\nx-ca-key:203803574\nx-ca-nonce:{uuid}\n{s.path+'?'+s.query[:-1]}".encode()
    sign = b64encode(hmac.new(ekey, to_enc, digestmod=hashlib.sha256).digest()).decode()
    return sign

createUuid() 和 get_sign() 两个函数,分别对应的是请求头中的x-ca-nonce,x-ca-signature 字段。

获取Cookie

要进入后台,那就需要登录,我们可以通过Cookie的方式。本来想从登录后的响应头中获取Cookie,但最后老是失败。

后面就直接弄了一个登录代码,登陆后获取它的Cookie。

def login():
    session = requests.session()
    session.cookies = cookielib.LWPCookieJar(filename='cookie/csdn.txt')##将cookie保存至文件
    ##获取微信登录的二维码的url
    response = session.get('https://open.weixin.qq.com/connect/qrconnect?appid=wx0ae11b6a28b4b9fc&scope=snsapi_login&redirect_uri=https%3A%2F%2Fpassport.csdn.net%2Fv1%2Fregister%2FpcAuthCallBack%3FpcAuthType%3Dweixin&state=csdn&login_type=jssdk&self_redirect=default&style=white&href=https://csdnimg.cn/release/passport/history/css/replace-wx-style.css',verify=False)
    uuid = re.findall('<img class="qrcode lightBorder" src="(.*?)" />',response.text)[0]
    img_url = 'https://open.weixin.qq.com' + uuid
    t= show_code(img_url)
    t.start()
    uuid = uuid.split('/')[-1]
    url = 'https://long.open.weixin.qq.com/connect/l/qrconnect?uuid='+uuid
    while 1:
        print(url)
        response = session.get(url,verify=False)
        code = re.findall("window.wx_code='(.*?)'",response.text)
        print(code)
        if code != ['']:
            break
        time.sleep(1)

    url = 'https://passport.csdn.net/v1/register/pcAuthCallBack?pcAuthType=weixin&code=%s&state=csdn' % code[0]
    print(url)
    session.get(url)
    session.cookies.save()
    print('登录成功!')

将Cookie保存在txt中:
在这里插入图片描述

获取文章ID列表

此部分是通过scrapy来做的(习惯了)。查看网页源码可知,文章ID在如下位置:
在这里插入图片描述

    def start_requests(self):
        urls = [
            'https://blog.csdn.net/qq_35524157',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)  
    def parse(self, response):
        blogIdList = response.css('div.article-item-box::attr(data-articleid)').extract()
        filename = 'CSDNSpider/spiders/blogIdList.txt'  
        f = open(filename, "a+") 
        for i in blogIdList:
            print(i)
            f.write(i)  
            f.write('\n')  
        f.close() 

start_requests函数爬取页面,将结果交给parse函数处理。获取到文章ID后保存至文件中。
在这里插入图片描述

获取markdown内容

获取单篇文章内容:

def getArticleDetail(url):
    uuid = createUuid()
    sign = get_sign(uuid,url)
    headers = {}
    headers['x-ca-key'] = "2038xxx4"
    headers['x-ca-nonce'] = uuid
    headers['x-ca-signature'] = sign
    headers['x-ca-signature-headers'] = "x-ca-key,x-ca-nonce"
    session = requests.session()

    session.cookies = cookielib.LWPCookieJar(filename='cookie/csdn.txt')
    session.cookies.load()
    data = session.get(url,headers=headers).json()
    return data

用前面写好的createUuid() 和 get_sign() 两个函数生成请求头中的x-ca-nonce,x-ca-signature 字段,读取保存在文件中的Cookie,发起请求。

以上则完成了一篇博客markdown内容的爬取,最后用保存在文件中的文章ID,获取全量的文章:

	url = "https://blog.csdn.net/qq_35524157"  # 更改为你自己的csdn博客主页地址
    article_list = get_all(url)

    for article in article_list:
        url = "https://bizapi.csdn.net/blog-console-api/v3/editor/getArticle?id=%s&model_type="%article
        text = getArticleDetail(url)
        markdown = text['data']['markdowncontent']
        title = text['data']['title']
        try:
            if markdown:
                for i in ["?", "、", "\\", "/", "*", '"', ":", "<", ">", "|"]:
                    title = title.replace(i, "-")
                print("文章\\%s.md" % title)
                with open("文章\\%s.md" % title, 'a',encoding='utf8') as f:
                    print(markdown)
                    f.write(markdown)
        except Exception as e:
            print("error", e)

结果如下:
在这里插入图片描述
在这里插入图片描述

源码获取

关注下方公众号,回复“CSDN_Spider”,即可获取源码。该公众号将不定期分享一些小demo、小项目以及学习心得

秀宇笔记

往期文章:

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值