Python爬虫实战:抓取马云微博数据详解

向北走
向北走
发布时间:2026-10-13 | 4人浏览过
原创

本文通过Python代码演示如何抓取马云的微博内容。首先利用浏览器开发者工具分析Ajax请求,识别GET请求中的关键参数及分页机制。接着解析返回的JSON数据,提取cardlistInfo中的总数量及cards中的微博正文、点赞、评论和转发数。最后结合Requests与PyQuery库,实现批量获取并保存微博信息至本地文件。

本文通过具体实例介绍使用Python抓取马云微博数据的方法,供读者参考学习。

分析请求

在浏览器中启用Ajax的XHR过滤器,持续滑动页面加载新微博,可观察到系统不断发出Ajax请求。

选取其中一个请求进行参数分析,点击该请求进入详情页面,具体界面如图所示:

该请求为GET类型,包含6个参数:display、retcode、type、value、containerid和page。对比多个请求发现,仅page参数发生变化,显然该参数用于控制分页。

分析响应

响应结构如图所示:

响应内容为JSON格式,浏览器开发者工具已自动解析以便查看。关键信息分为cardlistInfo和cards两部分。展开cardlistInfo,其中包含total字段,代表微博总数,据此可估算分页数量。

cards中还有一个重要字段mblog,展开后可见其包含微博的具体信息,如attitudes_count(点赞数)、comments_count(评论数)、reposts_count(转发数)、created_at(发布时间)以及text(微博正文)。这些数据格式规范,便于提取。

每次请求接口可获取10条微博,只需调整page参数即可。通过简单的循环结构,即可获取全部微博内容。

实战演练

接下来编写程序模拟上述Ajax请求,以爬取马云的所有微博。

首先定义一个方法获取每次请求的结果。由于page是可变参数,将其作为方法参数传入,代码如下:

from urllib.parse import urlencode
import requests
base_url = 'https://m.weibo.cn/api/container/getIndex?'
headers = {
  'Host': 'm.weibo.cn',
  'Referer': 'https://m.weibo.cn/u/2145291155',
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
  'X-Requested-With': 'XMLHttpRequest',
}
def get_page(page):
  params = {
    'display': '0',
    'retcode': '6102',
    'type': 'uid',
    'value': '2145291155',
    'containerid': '1076032145291155',
    'page': page
  }
  url = base_url + urlencode(params)
  try:
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
      return response.json()
  except requests.ConnectionError as e:
    print('Error', e.args)

代码中定义base_url表示请求URL的前半部分,随后构建参数字典。其中display、retcode、type、value、containerid为固定参数,page为可变参数。调用urlencode()将参数转换为URL GET请求格式,例如display=0&retcode=6102&type=uid&value=2145291155&containerid=1076032145291155&page=2。将base_url与参数拼接形成完整URL,使用Requests发送请求并传入headers。若响应状态码为200,则调用json()方法解析内容并返回;否则不返回信息;若出现异常,则捕获并打印异常信息。

随后定义解析方法,从结果中提取所需信息,如微博正文、点赞数、评论数和转发数。遍历cards,获取mblog中的各项数据,赋值给新字典后返回。

from pyquery import PyQuery as pq
def parse_page(json):
  if json:
    items = json.get('cards')
    for item in items:
      item = item.get('mblog')
      weibo = {}
      weibo['微博内容:'] = pq(item.get('text')).text()
      weibo['转发数'] = item.get('attitudes_count')
      weibo['评论数'] = item.get('comments_count')
      weibo['点赞数'] = item.get('reposts_count')
      yield weibo

此处使用PyQuery去除正文中的HTML标签。

最后遍历page参数,打印提取到的结果。

if __name__ == '__main__':
  for page in range(1, 50):
    json = get_page(page)
    results = parse_page(json)
    for result in results:
      print(result)

此外,可添加一个方法将结果保存至本地TXT文件。

def save_to_txt(result):
  with open('马云的微博.txt', 'a', encoding='utf-8') as file:
    file.write(str(result) + '\n')

代码整理

import requests
from urllib.parse import urlencode
from pyquery import PyQuery as pq
base_url = 'https://m.weibo.cn/api/container/getIndex?'
headers = {
  'Host': 'm.weibo.cn',
  'Referer': 'https://m.weibo.cn/u/2145291155',
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
  'X-Requested-With': 'XMLHttpRequest',
}
max_page = 50
def get_page(page):
  params = {
    'display': '0',
    'retcode': '6102',
    'type': 'uid',
    'value': '2145291155',
    'containerid': '1076032145291155',
    'page': page
  }
  url = base_url + urlencode(params)
  try:
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
      return response.json(), page
  except requests.ConnectionError as e:
    print('Error', e.args)
def parse_page(json, page: int):
  if json:
    items = json.get('data').get('cards')
    for index, item in enumerate(items):
      if page == 1 and index == 1:
        continue
      else:
        item = item.get('mblog')
        weibo = {}
        weibo['微博内容:'] = pq(item.get('text')).text()
        weibo['转发数:'] = item.get('attitudes_count')
        weibo['评论数:'] = item.get('comments_count')
        weibo['点赞数:'] = item.get('reposts_count')
        yield weibo
def save_to_txt(result):
  with open('马云的微博.txt', 'a', encoding='utf-8') as file:
    file.write(str(result) + '\n')
if __name__ == '__main__':
  for page in range(1, max_page + 1):
    json = get_page(page)
    results = parse_page(*json)
    for result in results:
      print(result)
      save_to_txt(result)

本文内容参考崔庆才所著《python3 网络爬虫开发实战》。

希望本文所述内容对大家的Python程序设计有所帮助。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表