引言

不知从何时起,10.24变成了程序员的节日,首先祝大家节日快乐!代码永无bug!

小编最近突然有点怀旧,想到了一个古老的网站——校内网(人人网),在小编还在读大学的那个时间,校内网真的是火的一塌糊涂,那时候的同学每天都在不停的刷校内,找同学,发布新鲜事。然而世事难料,谁也不曾想到当时那么火的校内网现在变得这么凄凉,如果不是刻意去想,可能都想不到这个网站。当想到这个网站的时候,小编突然想去访问一下这个网站,打开浏览器,输入用户名密码,还好,账号能够登陆。看着自己的好友列表,很想知道他们当时都在哪个城市。所以就写了几行代码,查询一下,也就有了今天的项目。

需求分析

爬取校内网个人主页的好友列表,然后再一次访问好友的好友列表页面,获取用户的城市信息。

需要源码的同学可以关注公众号,回复“校内网”获取源码。

知识点

爬取数据:WebDriver

多线程:ThreadPoolExecutor

图形分析:pyecharts

数据库:Mongo

获取好友列表

由于使用WebDriver操作浏览器,模拟用户登录操作,所以网页不需要进行过多的分析,只要能够定位控件位置即可。此处说一下逻辑,首先登陆校内网→访问个人主页→访问个人好友页面→提取好友信息(包括:姓名,好友主页地址,省份)→将提取的信息存入mongoDB。

从mongoDB中读取需要爬取的好友列表(用status标识)→访问好友个人主页(此处由于校内网限制,不能直接访问,需要登录自己账号后才可访问)→访问好友的好友列表→提取好友信息→将提取的信息存入mongoDB。

此处本应可以无限循环,例如我们提取到了好友的好友列表后,还可以提取好友的好友的好友列表。但是由于校内网隐私设置,我们无法访问好友的好友的好友列表页面,此处只能作罢。

之前听说过一句话,大概意思是“通过六个人,你可以认识世界上任何一个人”,本来还想着通过校内查询六次看看能够查询到多少人,结果受到校内设置影响,只能查询一次。

以下是部分代码:

登陆校内网:

def login(driver,url,username,pwd):driver.get(url)# 输入用户名input_text = WebDriverWait(driver,timeout).until(lambda d: d.find_element_by_id("email"))input_text.send_keys(username)print("输入用户名 ok")# 输入密码password = WebDriverWait(driver,timeout).until(lambda d: d.find_element_by_id("password"))password.send_keys(pwd)print("输入密码 ok")# 检查是否有需要输入验证码check_code(driver)# 点击登录按钮login_button = WebDriverWait(driver,timeout).until(lambda d: d.find_element_by_id("login"))login_button.click()print("点击登录 ok")# 进入个人主页hd_name = WebDriverWait(driver,timeout).until(lambda d: d.find_element_by_class_name("hd-name"))href = hd_name.get_attribute("href")print("找到个人主页地址 ok")return  href

爬取个人主页好友列表:

def get_my_friends_info_list(driver,href):# 访问个人主页地址driver.get(href)name = driver.titleprint("访问%s的个人主页 ok"%name)# 进入好友列表页面friends_button = WebDriverWait(driver,timeout).until(lambda d: d.find_element_by_xpath('//*[@id="specialfriend-box"]/div[1]/div/h5/a'))friends_button.click()print("进入%s好友列表 ok"%name)# 等待5s,加载数据time.sleep(5)# 如果滚动条不是在页面最下方,证明列表需要加载,下拉至页面最下方len_after = 0len_before = 1# 如果下拉后的好友数量不等于下拉前好友的数量,就继续下拉页面while len_after != len_before:friends_list = WebDriverWait(driver, timeout).until(lambda d: d.find_elements_by_class_name("friend-detail"))# 获取下拉之前的好友数量len_before = len(friends_list)# 下拉至页面最底端js = "window.scrollTo(0,document.body.scrollHeight)"driver.execute_script(js)time.sleep(2)friends_list = WebDriverWait(driver, timeout).until(lambda d: d.find_elements_by_class_name("friend-detail"))# 获取下拉后的好友数量len_after = len(friends_list)print("滚动条向下滚动到底部一次")# 定位 friend-detail 标签friends_list = WebDriverWait(driver, timeout).until(lambda d: d.find_elements_by_class_name("friend-detail"))print("定位li标签 ok")# 定位 .friend-detail a 标签personal_home_pages = WebDriverWait(driver, timeout).until(lambda d:d.find_elements_by_css_selector(".friend-detail a"))print("定位a标签 ok")# 定位省份信息provinces_list = WebDriverWait(driver, timeout).until(lambda d: d.find_elements_by_class_name("friends-loc-info"))print("定位省份信息 ok")# 将定位的信息组装成字典并写入数据库for i in range(len(friends_list)):friends_info = {"data_id":friends_list[i].get_attribute("data-id"),"name":friends_list[i].get_attribute("data-name"),"id":friends_list[i].get_attribute("id"),"personal_home_page":personal_home_pages[i].get_attribute("href"),"province":provinces_list[i].get_attribute("title"),"status":0,"from":name,}print(friends_info["province"], friends_info["name"])#将获取到的数据写入数据库write_to_mongo(friends_info,i,name)driver.quit()

存储数据到mongoDB:

def write_to_mongo(friends_info,i,name):# 将数据写入数据库curr = pymongo.MongoClient()database = curr["renren"]coll = database['friends']coll.insert(friends_info)print("%s的第%s个好友写入数据库成功"%(name,i+1))curr.close()

数据分析:

def fenxi():# 读取数据库中的数据curr = pymongo.MongoClient()database = curr["renren"]coll = database['friends']friends_list_all_find = coll.find({})friends_list_all = []for f in friends_list_all_find:friends_list_all.append(f)curr.close()# 统计省份信息result = {}for f in friends_list_all:if f["province"] not in result.keys():result[f["province"]] = 1else:result[f["province"]] += 1# 对统计数据进行过滤,去除没有省份的数据和小于100的数据result_gt100 = {}for k,v in result.items():if v >= 100:if k.strip():result_gt100[k] = v# 对数据按照省份值进行排序result_gt100_sorted = sorted(result_gt100.items(), key=lambda x: x[1], reverse=True)# 统计出key列表和value列表,下面生成统计图使用key = []value = []for k in result_gt100_sorted:key.append(k[0])value.append(k[1])# 柱形图bar = Bar("柱状图",width=2000,height=1000)bar.add("",key,value,is_label_show=True)bar.render(path="柱状图.html")# 全国地图map = Map("全国地图示例", width=2000, height=1000)map.add("", key, value, maptype='china',is_visualmap=True, visual_text_color="#000",is_map_symbol_show = False,visual_range=[0, 1000])map.render(path="地图.html")# 词云图wordcloud = WordCloud(width=2000, height=1000)wordcloud.add("", key, value, word_size_range=[20, 100])wordcloud.render(path="词云.html")

数据分析结果

本人校内网好友154位,通过这154位好友,一共抓取到了27215位好友信息(本人笔名27315,跟这个数字就差100),这里面未对好友进行去重,如果想要更精准一些,需要按照id去重。其中一位同学居然有3345个好友。。。嗯,是在下输了。

爬取到这些结果后,对数据进行了过滤,去除掉小于100的数据,再去除掉空数据(空数据是因为有些人未设置地区属性)。下面是结果分析。

地区分布柱形图:

可以看到有一个省份独占鳌头,相信同学们应该能够通过此图猜到小编是哪个省份的了。没错,就是排在第一位的黑龙江。

去除掉黑龙江之后,我们再来看一下结果:

省份还是比较平均的。

地图分布:

通过此图可以看见,好友分布由东北向西南递减。注:空白地区不是没有数据,而是数据过少被过滤掉了。

最后看下词云结果:

源码

链接:https://pan.baidu.com/s/1yXS3ryDV2PfFFKN9xdjZAg 密码:k4nz

以上内容为第一次爬取,后来在朋友的建议下做了优化:

昨天发布了爬取校内网好友分布的代码,然而还不够完善,在多线程的部分听取了一位朋友的意见,使用了submit方法,保证可以循环多次。另外将提取好友信息的部分单独拿出来做成了一个方法,方便代码以后的管理。由于是在昨日的代码中进行了优化,这次我就不写内容了,直接放上源代码。大家可以按需下载。

想要提醒大家的是,多线程如果开的太多,会导致校内网在登陆的时候使用验证码验证,目前还没有有效的自动识别验证码的方法,所以只能开少量线程,本人目前开的是3个,实测5个多线程在爬取第二轮的时候就会出现验证码,大家还是要控制爬取速度。

源码:

链接:https://pan.baidu.com/s/1RWQaR-MJbBH-CdRyIr994g 密码:kt42

【实战】还记得校内网么(人人网)?当年的同学都在哪?爬取一下就知道相关推荐

  1. 什么你还不知道招聘信息,小唐来教你——最新2021爬取拉勾网招聘信息(一)

    文章目录 前言 一.准备我们的库 二.分析分析 三. 代码 四.数据展示 小唐的心路历程 上一篇:没有啦! 下一篇:什么你还不知道招聘信息,小唐来教你--最新2021爬取拉勾网招聘信息(二) 前言 有 ...

  2. 什么你还不知道招聘信息,小唐来教你——最新2021爬取拉勾网招聘信息(二)

    文章目录 前言 一.准备我们的库 二.数据清洗 三.核密度图及词云制作 四.完整代码 五.扩展 上一篇:什么你还不知道招聘信息,小唐来教你--最新2021爬取拉勾网招聘信息(一) 下一篇:没有拉! 前 ...

  3. 爬取网易云音乐个人动态中的视频(Ⅲ): 实现爬取过程

    回顾 有了 爬取网易云音乐个人动态中的视频(Ⅰ) 和 爬取网易云音乐个人动态中的视频(Ⅱ) 的铺垫, 编写爬虫的代码便显得没那么突出了. 实现 直接show代码! 给出加密的代码 encrypt_ap ...

  4. python网易云听歌时长_用Python爬取10w条网易云音乐热评并进行分析的方法总结

    有个段子讲"十年文案老司机,不如网易评论区,网易文豪遍地走,评论全部单身狗",网易云音乐的评论区也一直都是各类文案大神的聚集地. 那么我们普通用户到底如何成为网易云音乐评论里的热评 ...

  5. 【代码】网易云音乐(周杰伦-晴天)评论的爬取

    参考爬取网易云音乐评论,典型的ajax加载,大多人是去破解js加密,有点繁琐. 爬取周杰伦-晴天这一条评论,因为数据量稍大.以后爬取整个歌手. 这是加密api的情况: import requestsd ...

  6. python爬取网易云歌单_详解python selenium 爬取网易云音乐歌单名

    目标网站: 首先获取第一页的数据,这里关键要切换到iframe里 打印一下 获取剩下的页数,这里在点击下一页之前需要设置一个延迟,不然会报错. 结果: 一共37页,爬取完毕后关闭浏览器 完整代码: u ...

  7. python爬取去哪网数据_用户观点:企查查数据爬取技术与Python 爬取企查查数据...

    主体数据来源是全国工商信用网但是每个省的工商系统都不同,要针对每个省的工商系统单独写爬虫每个省的验证码也不同,也要单独做.企查查的原理不是主动爬去数据,而是有人查询该企业时,如果自己的数据库没有该企业 ...

  8. Python爬虫实战(六):对某一关键词的某度指数数据的爬取(2022年5月更新)

    追风赶月莫停留,平芜尽处是春山. 文章目录 追风赶月莫停留,平芜尽处是春山. 一.网页分析 二.接口分析 url分析 返回数据分析 三.编写代码 获取数据 解密 完整代码 2022.5更: 多加了一个 ...

  9. 09校内网、人人网、千橡公司笔试题

    笔试题: A数学逻辑 B数据结构   二叉树,散列表,栈的出栈序列,排序的时间复杂度, C网络基础   IP地址,ICMP协议,服务及其端口号,TCP的三次握手过程 D操作系统   防止死锁的方法,L ...

  10. python爬取网易云音乐歌单_【python】爬取并批量下载网易云歌单,嗨翻暑假!

    [Python] 纯文本查看 复制代码# 利用 Selenium 抓取淘宝商品并用 PyQuery 解析得到商品的图片.名称.价格.购买人数. # 店铺名称.店铺所在地信息,并将其保存到MongoDB ...

最新文章

  1. LeetCode 36 Valid Sudoku(有效数独)(*)
  2. 树莓派学习——文件传输
  3. leetcode 521. 最长特殊序列 Ⅰ(Java)
  4. XCTF-MISC-新手区-SimpleRAR
  5. 计算机系统基础:校验码知识笔记
  6. 《javaScript100例|04》自动播放——Js幻灯片缓冲效果
  7. Altium Designer之Preferences
  8. 小程序分享到朋友圈_微信内测开放小程序分享到朋友圈功能
  9. 波音可以自己做安全认证,错误在于故意掩盖问题
  10. 从抖音到“奶头乐“,它是如何一步步毁掉我们的?
  11. 文法去除空产生式_文法化简 (CFG Simplification) 翻译
  12. 带你了解“不拘一格去创新,别出心裁入场景”的锐捷
  13. 制作U盘启动盘(无广告)
  14. 第一单元 用python学习微积分(五) 隐函数微分法和逆函数导数(上)- 隐函数微分
  15. 乘法计算机公式,在word中乘法的函数公式计算公式
  16. 南都周刊:别了,老兵乔布斯
  17. Roadblock for Mac(Safari广告内容拦截软件)
  18. 学做网站有哪些注意事项(上)
  19. java鬼吹灯搬山法杖_《鬼吹灯》:深度解析搬山鹧鸪哨,为寻找雮尘珠的悲惨人生...
  20. java p12 ssl_OpenSSL 1.0.0生成p12、jks、crt等格式SSL数字证书的全过程合集

热门文章

  1. Git下载、安装及环境配置(超详细)
  2. Deep Adversarial Decomposition: A Unified Framework for Separating Superimposed Images 论文阅读笔记
  3. Mysql 索引失效场景
  4. url在传递的过程中要先进行一个转码,然后再进行解码,url的转码,url的解码
  5. 美团外卖数据采集接口
  6. 【R语言-P值校正(BH)】
  7. SQL Server 公用表表达式(CTE)
  8. virtualbox安装增强功能失败解决办法与原因
  9. RJ45-线序 586B 白橙 橙 白绿 蓝 白蓝 绿 白棕 棕
  10. 用PHPphpstudy写一个可以登录的简单网页