1. 效果图,其中涉及一些真名我就打码了,还有qq号我也打码了,见谅


2. 解析,通过访问qq群官网并登陆

点击传送门

3. 分析登陆的元素,下图一目了然,怎么获取这个登陆元素应该都知道了

4. 代码奉上

url = 'https://qun.qq.com/'
# 构建谷歌驱动器
browser = webdriver.Chrome()
# 请求url
browser.get(url)
# 模拟登陆,首先找到登陆的id,并点击
browser.find_element_by_css_selector('#headerInfo p a').click()

5. 点击之后出现这么一个框框(这个框框可把我折磨的阿)原因是这样的,寻常的获取这个框框是不能获取到的

6. 先看看这个框所在的位置,这个框框竟然在另一个html代码里面,也就是说在浏览器看的时候,出现了两个html标签,老实说,我是第一次看到这种情况的,奈何我的html也不好,连入门都算不上,没办法,我就去百度了,果然黄天不负有心人,说是因为iframe这个标签可以再放html代码,所以就是这种情况了

7. 既然知道了是怎么一回事之后,那就可以继续操作了,首先我们先找到iframe这个标签,然后获取它的src属性,这个链接就是这个框框登陆的链接了,如果不获取这个iframe标签的src属性,那么我们使用selenium是获取不到这个框框的元素的。

# 点击之后会弹出一个登陆框,这时候我们用显示等待来等待这个登陆框加载出来
WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#loginWin iframe'))
)
print('登陆框已加载')
# 登陆框加载之后,我们发现整个登陆框其实就是另一个网网页
# 如果在原网页操作这个登陆框的话,是不能操作的
# 所以我们只需要提取iframe标签的src属性,然后再去访问这个url即可实现
# 自动登陆
# 找到iframe标签并获取src
iframe_url = browser.find_element_by_css_selector('#loginWin iframe').get_attribute('src')
# 再访问这个url
browser.get(iframe_url)
# 找到快捷登陆的头像并点击
# 首先用显示等待这个头像已经加载完成
WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.ID, 'qlogin_list'))
)
browser.find_element_by_css_selector('#qlogin_list a').click()
print('登陆成功')

8. 登陆成功之后我们需要的是群管理,是ul标签的第四个li标签,通过xpath获取

# 登陆成功之后,我们就找到群管理的标签并点击,首先等待这个元素加载完成
WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.XPATH, './/ul[@id="headerNav"]/li[4]'))
)
browser.find_element_by_xpath('.//ul[@id="headerNav"]/li[4]').click()

9. 点击群管理之后,进入群管理界面,我们需要的是成员管理

# 点击之后,我们找到成员管理标签并点击
WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'color-tit'))
)
browser.find_element_by_class_name('color-tit').click()

10. 点击成员管理之后会重新新建一个窗口,这个时候就会出现句柄,我们需要将当然窗口的句柄切换到新打开的这个界面,不然的话,是获取不到新打开界面的信息的,注释已经写了

# 打印全部窗口句柄
# print(browser.window_handles)
# 打印当前窗口句柄
# print(browser.current_window_handle)
# 注意这里点击成员管理之后会自动跳转到一个新窗口打开这个页面
# 所以我们需要将窗口句柄切换到这个新窗口browser.switch_to.window(browser.window_handles[1])# 解释一下browser.switch_to.window是获取当前一共有几个窗口
# 这里是2个
# browser.switch_to.window这个是指定当前游标切换到哪个窗口
# 其实也可以这么写
# all_window = browser.switch_to.window返回的是一个列表
# browser.switch_to.window(all_window[1])
# 效果是一样的

11. 我们需要的是我加入的群信息

# 切换句柄之后,我们显示等待窗口出来WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'my-all-group')))# 筛选出我加入的群标签lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[2]/li')

12. 遍历列表,取出信息

# 遍历
num= 0
while True:if num == len(lis):breaktry:# 按顺序选择群并获取信息# 先点击该群获取成员信息lis[num].click()# 显示等待信息加载完成WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'list')))# 获取该群当前有多少人,后面翻页需要groupMemberNum = eval(browser.find_element_by_id('groupMemberNum').text)# 每一次翻页都会刷新21条信息,所以写个循环# 这里加1是因为假如一个群有36人,那么count=1,如果循环的话就不会翻页了# 也就是只能抓到一页的数据,大家可以自己想想其中的流程就知道了count = groupMemberNum // 21 + 1# 这里我只爬取每个群的一部分,如果想爬取全部成员信息# 请注释下面的if语句if count > 2:count = 1# 每次循环都进行翻页# while count:#     count -= 1##     browser.execute_script('document.documentElement.scrollTop=100000')#     time.sleep(2)time.sleep(2)# 开始获取成员信息trs = browser.find_elements_by_class_name('mb')if trs:# 遍历for tr in trs:tds = tr.find_elements_by_tag_name('td')[2:]if len(tds) == 8:# qq网名qq_name = tds[0].text# 群名称group_name = tds[1].text# qq号qq_number = tds[2].text# 性别gender = tds[3].text# qq年龄qq_year = tds[4].text# 入群时间join_time = tds[5].text# 等级(积分)level = None# 最后发言时间end_time = tds[6].text# 声明一个字典存储数据data_dict = {}data_dict['qq_name'] = qq_namedata_dict['group_name'] = group_namedata_dict['qq_number'] = qq_numberdata_dict['gender'] = genderdata_dict['qq_year'] = qq_yeardata_dict['join_time'] = join_timedata_dict['level'] = leveldata_dict['end_time'] = end_timeprint(data_dict)elif len(tds) == 9:# qq网名qq_name = tds[0].text# 群名称group_name = tds[1].text# qq号qq_number = tds[2].text# 性别gender = tds[3].text# qq年龄qq_year = tds[4].text# 入群时间join_time = tds[5].text# 等级(积分)level = tds[6].text# 最后发言时间end_time = tds[7].text# 声明一个字典存储数据data_dict = {}data_dict['qq_name'] = qq_namedata_dict['group_name'] = group_namedata_dict['qq_number'] = qq_numberdata_dict['gender'] = genderdata_dict['qq_year'] = qq_yeardata_dict['join_time'] = join_timedata_dict['level'] = leveldata_dict['end_time'] = end_timedata_list.append(data_dict)print(data_dict)browser.find_element_by_id('changeGroup').click()time.sleep(3)WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'ui-dialog')))lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[2]/li')num += 1except Exception as e:lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[2]/li')num += 1continue

13. 一些需要说明的思路,num是判断是否爬完这些群,如果爬完了,那就退出循环


14. 因为lis是每个群,所以lis[num].click()是点击当前的群,进入查看群成员信息

15. 最后需要注意的就是当我们爬取当前群的成员信息之后,怎么切换到下一个群


16. 完整代码附上

# 导入需要的包
# 爬取qq群的成员信息
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import json
import csv# 开始登陆
def login_spider():url = 'https://qun.qq.com/'# 构建谷歌驱动器browser = webdriver.Chrome()# 请求urlbrowser.get(url)# 模拟登陆,首先找到登陆的id,并点击browser.find_element_by_css_selector('#headerInfo p a').click()# 点击之后会弹出一个登陆框,这时候我们用显示等待来等待这个登陆框加载出来WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#loginWin iframe')))print('登陆框已加载')# 登陆框加载之后,我们发现整个登陆框其实就是另一个网网页# 如果在原网页操作这个登陆框的话,是不能操作的# 所以我们只需要提取iframe标签的src属性,然后再去访问这个url即可实现# 自动登陆# 找到iframe标签并获取是如此熟悉iframe_url = browser.find_element_by_css_selector('#loginWin iframe').get_attribute('src')# 再访问这个urlbrowser.get(iframe_url)# 找到快捷登陆的头像并点击# 首先用显示等待这个头像已经加载完成WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.ID, 'qlogin_list')))browser.find_element_by_css_selector('#qlogin_list a').click()print('登陆成功')return browser# 切换句柄操作
def switch_spider(browser):# 登陆成功之后,我们就找到群管理的标签并点击,首先等待这个元素加载完成WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.XPATH, './/ul[@id="headerNav"]/li[4]')))browser.find_element_by_xpath('.//ul[@id="headerNav"]/li[4]').click()# 点击之后,我们找到成员管理标签并点击WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'color-tit')))browser.find_element_by_class_name('color-tit').click()# 打印全部窗口句柄# print(browser.window_handles)# 打印当前窗口句柄# print(browser.current_window_handle)# 注意这里点击成员管理之后会自动跳转到一个新窗口打开这个页面# 所以我们需要将窗口句柄切换到这个新窗口browser.switch_to.window(browser.window_handles[1])# 解释一下browser.switch_to.window是获取当前一共有几个窗口# 这里是2个# browser.switch_to.window这个是指定当前游标切换到哪个窗口# 其实也可以这么写# all_window = browser.switch_to.window返回的是一个列表# browser.switch_to.window(all_window[1])# 效果是一样的return browser# 开始采集数据
def start_spider(browser):# 声明一个列表存储字典data_list = []# 切换句柄之后,我们显示等待窗口出来WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'my-all-group')))# 筛选出我加入的群标签lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[2]/li')# 遍历num = 0while True:try:# 按顺序选择群并获取信息# 先点击该群获取成员信息lis[num].click()# 显示等待信息加载完成WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'list')))# 获取该群当前有多少人,后面翻页需要groupMemberNum = eval(browser.find_element_by_id('groupMemberNum').text)# 每一次翻页都会刷新21条信息,所以写个循环# 这里加1是因为假如一个群有36人,那么count=1,如果循环的话就不会翻页了# 也就是只能抓到一页的数据,大家可以自己想想其中的流程就知道了count = groupMemberNum // 21 + 1# 这里我只爬取每个群的一部分,如果想爬取全部成员信息# 请注释下面的if语句if count > 5:count = 5# 每次循环都进行翻页while count:count -= 1browser.execute_script('document.documentElement.scrollTop=100000')time.sleep(2)time.sleep(3)# 开始获取成员信息trs = browser.find_elements_by_class_name('mb')if trs:# 遍历for tr in trs:tds = tr.find_elements_by_tag_name('td')[2:]if len(tds) == 8:# qq网名qq_name = tds[0].text# 群名称group_name = tds[1].text# qq号qq_number = tds[2].text# 性别gender = tds[3].text# qq年龄qq_year = tds[4].text# 入群时间join_time = tds[5].text# 等级(积分)level = None# 最后发言时间end_time = tds[6].text# 声明一个字典存储数据data_dict = {}data_dict['qq_name'] = qq_namedata_dict['group_name'] = group_namedata_dict['qq_number'] = qq_numberdata_dict['gender'] = genderdata_dict['qq_year'] = qq_yeardata_dict['join_time'] = join_timedata_dict['level'] = leveldata_dict['end_time'] = end_timeprint(data_dict)elif len(tds) == 9:# qq网名qq_name = tds[0].text# 群名称group_name = tds[1].text# qq号qq_number = tds[2].text# 性别gender = tds[3].text# qq年龄qq_year = tds[4].text# 入群时间join_time = tds[5].text# 等级(积分)level = tds[6].text# 最后发言时间end_time = tds[7].text# 声明一个字典存储数据data_dict = {}data_dict['qq_name'] = qq_namedata_dict['group_name'] = group_namedata_dict['qq_number'] = qq_numberdata_dict['gender'] = genderdata_dict['qq_year'] = qq_yeardata_dict['join_time'] = join_timedata_dict['level'] = leveldata_dict['end_time'] = end_timedata_list.append(data_dict)print(data_dict)browser.find_element_by_id('changeGroup').click()time.sleep(3)WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'ui-dialog')))lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[2]/li')num += 1except Exception as e:continuereturn data_listdef main():browser = login_spider()browser = switch_spider(browser)data_list = start_spider(browser)# 将数据写入json文件with open('data_json.json', 'a+', encoding='utf-8') as f:json.dump(data_list, f)print('json文件写入完成')# 这里的编码格式不要写错了,不然会出现乱码,因为群里面的大神名字贼骚with open('data_csv.csv', 'w', encoding='utf-8-sig', newline='') as f:# 表头title = data_list[0].keys()# 声明writerwriter = csv.DictWriter(f, title)# 写入表头writer.writeheader()# 批量写入数据writer.writerows(data_list)print('csv文件写入完成')if __name__ == '__main__':main()

python爬虫——使用selenium爬取qq群的成员信息(全自动实现自动登陆)相关推荐

  1. Python爬虫使用selenium爬取qq群的成员信息(全自动实现自动登陆)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: python小爬虫 PS:如有需要Python学习资料的小伙伴可以 ...

  2. python抓取文献关键信息,python爬虫——使用selenium爬取知网文献相关信息

    python爬虫--使用selenium爬取知网文献相关信息 写在前面: 本文章限于交流讨论,请不要使用文章的代码去攻击别人的服务器 如侵权联系作者删除 文中的错误已经修改过来了,谢谢各位爬友指出错误 ...

  3. python爬虫——使用selenium爬取微博数据(一)

    python爬虫--使用selenium爬取微博数据(二) 写在前面 之前因为在组里做和nlp相关的项目,需要自己构建数据集,采用selenium爬取了几十万条微博数据,学习了很多,想在这里分享一下如 ...

  4. python爬虫——用selenium爬取淘宝商品信息

    python爬虫--用selenium爬取淘宝商品信息 1.附上效果图 2.淘宝网址https://www.taobao.com/ 3.先写好头部 browser = webdriver.Chrome ...

  5. Python爬虫入门 | 5 爬取小猪短租租房信息

    小猪短租是一个租房网站,上面有很多优质的民宿出租信息,下面我们以成都地区的租房信息为例,来尝试爬取这些数据. 小猪短租(成都)页面:http://cd.xiaozhu.com/   1.爬取租房标题 ...

  6. python爬虫:Selenium爬取B站视频标题、播放量、发布时间

    上次尝试了利用Ajax机制爬取B站视频播放量等数据(链接在下方),但是发现响应的JSON数据中没有发布时间的数据,这次决定用Selenium试一下. python爬虫:Ajax爬取B站视频标题.播放量 ...

  7. Python爬虫练习(爬取OJ题目和学校信息通知)

    爬取OJ题目和学校信息通知 一.爬取南阳理工OJ题目 1. 初步分析 2. 代码编写 二.爬取学校信息通知 1. 每页url分析 2. 每页内容爬取 总代码 三.总结 参考 一.爬取南阳理工OJ题目 ...

  8. Python爬虫使用selenium爬取天猫商品信息

    文章目录 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加高深的知识. 那么针对这三类人,我 ...

  9. python爬虫——scrapy+selenium爬取新浪微博及评论

    本文主要对爬取过程中所用到的知识做简单总结,最后有项目链接. 一.项目简介 本项目利用python的scrapy框架+selenium模拟登陆微博来爬取带有关键字的微博及微博下面的评论(1 .2级评论 ...

  10. Python爬虫实战之爬取QQ音乐之下载有版权的音乐(五)-1

    我这里使用的方法 比较简单 用神奇fiddler即可. 这些分两篇 第一篇定位音乐然后手动操作保存  第二篇自动下载 首先本篇下载的最近很火的一首歌叫 < 你的酒馆对我打了烊 > 这个音乐 ...

最新文章

  1. Python导入其他文件中的.py文件 即模块
  2. 为了在元宇宙里摸到东西,扎克伯格整出了一款新电子皮肤,成本6美元
  3. Java基础学习总结(28)——Java对各种排序算法的实现
  4. 【C++】欧几里德算法快速求最大公约数
  5. 暴雪帝国倾倒前的颓萎:积重难返辉煌渐淡
  6. java txtreader_一个简单的Java读写文件例子
  7. mysql的一些初步使用!mysqlcheck mysqladmin 建立删除修改表,库,等
  8. 【渝粤题库】陕西师范大学400005 中国传统文化 作业(专升本)
  9. LeetCode 524. 通过删除字母匹配到字典里最长单词(双指针)
  10. java开发项目实例_Alibaba内部出品Java突击手册,大量开发实战项目分享
  11. Fast-SCNN:多分支结构共享低级特征的语义分割网络
  12. 7-1 打印沙漏 (20 分)
  13. realme Q5系列核心规格曝光:80W快充加持 同价位绝无仅有
  14. 《Programming WPF》翻译 第8章 3.Storyboard
  15. 实习生如何在平淡无奇的工作中凸显自我价值?
  16. 耳朵大寿命长 由耳可辨疾病
  17. iMindMap邀您一起“约惠”开学季
  18. RK3288开发板,RK3288核心板,瑞芯微RK3288主板资料
  19. DNS协议——域名解析
  20. win10启动0xc0000001错误

热门文章

  1. 深度装机大师一键重装_“云骑士一键重装系统”,看标题就知道装系统原来如此简单...
  2. 固定日历 jeDate 日期控件 选择时间,没有相应的回调事件
  3. Flash Builder4.7 破解方法
  4. DBeaver - 一款免费开源的通用数据库工具
  5. [Linux系统编程/网络编程] 笔记目录
  6. 终极算法-机器学习和人工智能如何重塑世界:电子书
  7. java mdt_java – MST映射到当前是MDT的joda中的Denver时区.这是joda DateTimeZone中的错误吗?...
  8. 联想Y9000X Opencore引导黑苹果Catalina10.15.6安装教程
  9. 第 1 课:KNX 与 Arduino:硬件连接
  10. PHP 接收 UDP包_常用的抓包工具包含电脑端及手机端