简书爬ajax接口获取csrf,Python爬取简书主页信息

主要学习如何通过抓包工具分析简书的Ajax加载,有时间再写一个Multithread proxy spider提升效率。

1. 关键点:

使用单线程爬取,未登录,爬取简书主页Ajax加载的内容。主要有三个关键点:

抓包抓到的X-INFINITESCROLL: true、X-Requested-With: XMLHttpRequest、两个字段是固定的。

还有X-CSRF-Token这个key的value通过首次请求简书首页获得,用于爬取Ajax的下一页。

表单里的seen_snote_ids[]: xxxxx是文章的ID,如果下次请求不带上这个ID,会出现重复的数据

2. 效果图:

daa127a7e327c0b23d045a5b5e909492.png

3. 源代码:

# /usr/bin/env python3

# _*_ coding:utf-8 _*_

"""

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Name : Liu

Date : 2019/4/1 18:14

Version : Python 3.7.0

IDE : Pycharm-community-2018.2.4

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

"""

import requests

import re

import time

class JianshuSpider(object):

def __init__(self):

self.url = 'https://www.jianshu.com' # 主页URL

self.page = 5 # 爬取的页数

self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"}

def get_home_content(self):

# 请求

home_code = requests.get(self.url,headers=self.headers)

home_data = home_code.text

# 获取请求头部所需的 token

token = re.findall('',home_data)[0]

# 获取第一页所有文章的ID

id = re.findall('data-note-id="(\d*)"',home_data,re.S)

# 使用正则处理请求,获取文章的标题、链接、简介

home_page_article = self.parsing_codes(home_data)

# 打印

self.echo_content(home_page_article)

# 传入所需的token、id、爬取页数后,开始加载Ajax(爬取下一页)

self.get_next_content(token,id,self.page)

def get_next_content(self,token,id,pages):

# 使用for循环

for page in range(2,pages+1):

# 准备请求头部

headers = {

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",

"X-INFINITESCROLL": "true",

"X-Requested-With": "XMLHttpRequest",

"X-CSRF-Token": token

}

# 需要提交的表单

params = {

"page": page, # 页数

"seen_snote_ids[]": id # 帖子的ID

}

url = 'https://www.jianshu.com' # 请求的URL

# 发送请求

resp = requests.get(url,headers=headers,params=params)

# 使用正则处理请求,获取文章的标题、链接、简介

article = self.parsing_codes(resp.text)

# 打印内容

self.echo_content(article)

# 打印方法...

def echo_content(self,article):

for i in article: # 你可以不用这个方法,而是将其改为写入到文件的...

title = i[1] # 标题,

link = i[0] # 链接

desc = i[2] # 描述

print('[标题]:%s' % title)

print('[链接]:%s' % self.url + link)

print('[简介]:%s' % desc.lstrip())

time.sleep(0.1)

# 正则处理方法...

def parsing_codes(self,data):

article = re.findall('.*?(.*?).*?

(.*?)

',data, re.S)

return article

# ...?

if __name__ == '__main__':

jianshu = JianshuSpider()

jianshu.get_home_content()