写点什么

谁有粉?就爬谁!他粉多,就爬他!Python 多线程采集 260000+ 粉丝数据

作者:梦想橡皮擦
  • 2021 年 11 月 14 日
  • 本文字数:2758 字

    阅读完需:约 9 分钟

今天你想爬谁的粉呢?谁粉多,就爬谁。那谁有粉?沉默王二有粉。


今天咱们继续学习 Python 爬虫,从本篇博客开始进行短暂的(15 篇)多线程爬虫学习


第一篇就要采集 @沉默王二 的粉丝,坐拥 27W+ 读者,属实让人羡慕。

目标数据源分析

本次要抓取的数据源是 https://blog.csdn.net/qing_gee?type=sub&subType=fans,其中的 ID 可以切换为你希望采集的 ID,当然包括你自己的 ID。


该页面下滑刷新会自动请求一个 API 接口,即 https://blog.csdn.net/community/home-api/v1/get-fans-list?page=3&size=20&noMore=false&blogUsername=qing_gee,其中参数如下:


  • page:页码,根据目标人粉丝总数 / 20 计算获取即可;

  • size:每页数据,默认值 20;

  • noMore:无用;

  • blogUsername:博客用户名


同时在测试接口过程中,接口会返回异常数据,实测增加一个延时控制,可以大幅度提高接口数据返回稳定性。


{'code': 400, 'message': 'fail', 'data': None}
复制代码


正常接口数据返回如下图所示:


使用技术点说明

本次采用 Python 多线程实现数据的采集,编码使用 threading 模块进行多线程控制,本系列专栏从最简单的多线程开始进行学习,例如本例,一次性发起 5(可自定义)个请求。


完整代码如下所示,代码说明请参考注释部分与尾部说明


import threadingfrom threading import Lock, Threadimport timeimport osimport requestsimport random

class MyThread(threading.Thread): def __init__(self, name): super(MyThread, self).__init__() self.name = name
def run(self): global urls lock.acquire() one_url = urls.pop() print("正在爬取:", one_url) lock.release() print("任意线程等待随机时间") time.sleep(random.randint(1,3)) res = requests.get(one_url, headers=self.get_headers(), timeout=5)
if res.json()["code"] != 400: data = res.json()["data"]["list"] for user in data: name = user['username'] nickname = self.remove_character(user['nickname']) userAvatar = user['userAvatar'] blogUrl = user['blogUrl'] blogExpert = user['blogExpert'] briefIntroduction = self.remove_character( user['briefIntroduction'])
with open('./qing_gee_data.csv', 'a+', encoding='utf-8') as f: print(f'{name},{nickname},{userAvatar},{blogUrl},{blogExpert},{briefIntroduction}') f.write(f"{name},{nickname},{userAvatar},{blogUrl},{blogExpert},{briefIntroduction}\n") else: print(res.json()) print("异常数据", one_url) with open('./error.txt', 'a+', encoding='utf-8') as f: f.write(one_url+"\n") # 去除特殊字符
def remove_character(self, origin_str): if origin_str is None: return origin_str = origin_str.replace('\n', '') origin_str = origin_str.replace(',', ',') return origin_str # 获取随机UA请求头 def get_headers(self): uas = [ "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" ] ua = random.choice(uas) # 特别注意下述 cookie 部分,需要手动从开发者工具中进行复制,否则抓取到的数据,缺少nikename 与个人简介部分 headers = { "user-agent": ua, 'cookie': 'UserName=你的ID; UserInfo=你的UserInfo; UserToken=你的UserToken;', "referer": "https://blog.csdn.net/qing_gee?type=sub&subType=fans" } return headers

if __name__ == '__main__': lock = Lock() url_format = 'https://blog.csdn.net/community/home-api/v1/get-fans-list?page={}&size=20&noMore=false&blogUsername=qing_gee' urls = [url_format.format(i) for i in range(1, 13300)] l = [] while len(urls) > 0: print(len(urls)) for i in range(5): p = MyThread("t"+str(i)) l.append(p) p.start() for p in l: p.join()
复制代码


代码运行结果如下图所示:


上述代码用到了多线程,也同时用到了线程锁,简单的多线程代码可以抽象为下述内容。


简单的多线程代码:


import threadingimport time
def run(n): print('task', n) time.sleep(3)
if __name__ == '__main__': t1 = threading.Thread(target=run, args=('t1',)) t2 = threading.Thread(target=run, args=('t2',)) t1.start() t2.start()
复制代码


其中比较核心的代码是 threading.Thread,参数 target 后面的值是函数名,args 是传递的参数,注意必须为元组类型。


爬虫代码还是用了共享全局变量,简化代码如下所示,其中重点学习 lock=Lock() 部分代码,以及在使用全局变量前后的 lock.acquire()lock.release()。其中还用到了线程的 join 方法,该方法主要是为了让主线程等待子线程执行。


import threadingfrom threading import Lock,Threadimport time,os
def work(): global urls lock.acquire() # 获取一个 url one_url = urls.pop() lock.release()
print("得到的 URL 为",one_url)

if __name__ == '__main__': lock = Lock() url_format = 'https://blog.csdn.net/community/home-api/v1/get-fans-list?page={}&size=20&noMore=false&blogUsername=qing_gee' # 拼接URL,全局共享变量 urls = [url_format.format(i) for i in range(1, 13300)] l = [] # 开启线程数量 for i in range(3): p = Thread(target=work) l.append(p) p.start() for p in l: p.join()
复制代码


拿到这些数据,可以针对性的去描述一个作者的用户画像了,本部分在后续的博客中为大家单独开一篇详细介绍。


代码在数据清理部分,还有优化的空间,由于设置了 13300 页数据,故最终抓取到 26W+数据,查询了一下,存在 梦想橡皮擦



关注者中至少有 83 位博客专家,可以看到博客专家的个人简介写的都比较清楚,同时发现 jiangtao(CSDN 创始人)


收藏时间

代码下载地址:https://codechina.csdn.net/hihell/python120,可否给个 Star。


来都来了,不发个评论,点个赞,收个藏吗?


发布于: 2021 年 11 月 14 日阅读数: 11
用户头像

爬虫 100 例作者,蓝桥签约作者,博客专家 2021.02.06 加入

6 年产品经理+教学经验,3 年互联网项目管理经验; 互联网资深爱好者; 沉迷各种技术无法自拔,导致年龄被困在 25 岁; CSDN 爬虫 100 例作者。 个人公众号“梦想橡皮擦”。

评论

发布
暂无评论
谁有粉?就爬谁!他粉多,就爬他!Python 多线程采集 260000+ 粉丝数据