Python爬取简书主页信息

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

1. 关键点:

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

  • 抓包抓到的X-INFINITESCROLL: trueX-Requested-With: XMLHttpRequest、两个字段是固定的。
  • 还有X-CSRF-Token这个key的value通过首次请求简书首页获得,用于爬取Ajax的下一页。
  • 表单里的seen_snote_ids[]: xxxxx是文章的ID,如果下次请求不带上这个ID,会出现重复的数据

2. 效果图:

效果图

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('<meta name="csrf-token" content="(.*?)" />',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('<a class="wrap-img" href="(.*?)" target="_blank">.*?<a class="title" target="_blank" href=".*?">(.*?)</a>.*?<p class="abstract">(.*?)</p>',data, re.S)
        return article

# ...?
if __name__ == '__main__':
    jianshu = JianshuSpider()
    jianshu.get_home_content()
原文地址:https://www.cnblogs.com/liuhedong/p/10663862.html