使用Python爬取QQ群成员信息

直接贴代码

1import os 2from selenium import webdriver 3from selenium.webdriver.support.ui import WebDriverWait 4from selenium.webdriver.support import expected_conditions as EC 5from selenium.webdriver.common.by import By 6import time 7import json 8import csv 9import re 10 11qq = '' 12if qq == '': 13 qq = str(int(time.time())) 14# 初始化一些东西 15option = webdriver.ChromeOptions() 16option.binary_location = r'C:\Program Files\Google\Chrome\Application\chrome.exe' 17cmd_path = os.path.join(os.getcwd()) 18save_path = os.path.join(os.getcwd(), 'data', qq) 19if not os.path.exists(save_path): 20 os.mkdir(save_path) 21 22def test(): 23 # 构建谷歌驱动器 24 # browser = webdriver.Chrome(r'C:\Tools\chromedriver.exe', options=option) 25 # browser.get("https://www.baidu.com/") 26 return True 27 28 29# 开始登陆 30def login_spider(): 31 url = 'https://qun.qq.com/' 32 # 构建谷歌驱动器 33 browser = webdriver.Chrome(r'C:\Tools\chromedriver.exe', options=option) 34 # 请求url 35 browser.get(url) 36 # 模拟登陆,首先找到登陆的id,并点击 37 browser.find_element_by_css_selector('#headerInfo p a').click() 38 # 点击之后会弹出一个登陆框,这时候我们用显示等待来等待这个登陆框加载出来 39 WebDriverWait(browser, 1000).until( 40 EC.presence_of_all_elements_located( 41 (By.CSS_SELECTOR, '#loginWin iframe') 42 ) 43 ) 44 print('登陆框已加载') 45 # 登陆框加载之后,我们发现整个登陆框其实就是另一个网网页 46 # 如果在原网页操作这个登陆框的话,是不能操作的 47 # 所以我们只需要提取iframe标签的src属性,然后再去访问这个url即可实现 48 # 自动登陆 49 # 找到iframe标签并获取是如此熟悉 50 iframe_url = browser.find_element_by_css_selector('#loginWin iframe').get_attribute('src') 51 # 再访问这个url 52 browser.get(iframe_url) 53 # 找到快捷登陆的头像并点击 54 # 首先用显示等待这个头像已经加载完成 55 WebDriverWait(browser, 1000).until( 56 EC.presence_of_all_elements_located( 57 (By.ID, 'qlogin_list') 58 ) 59 ) 60 browser.find_element_by_css_selector('#qlogin_list a').click() 61 print('登陆成功') 62 return browser 63 64 65# 切换句柄操作 66def switch_spider(browser): 67 # 登陆成功之后,我们就找到群管理的标签并点击,首先等待这个元素加载完成 68 WebDriverWait(browser, 1000).until( 69 EC.presence_of_all_elements_located( 70 (By.XPATH, './/ul[@id="headerNav"]/li[3]') 71 ) 72 ) 73 browser.find_element_by_xpath('.//ul[@id="headerNav"]/li[3]').click() 74 # 点击之后,我们找到成员管理标签并点击 75 WebDriverWait(browser, 1000).until( 76 EC.presence_of_all_elements_located( 77 (By.CLASS_NAME, 'body') 78 ) 79 ) 80 browser.find_element_by_xpath('.//div[@class="body"]/ul[1]/li[1]').click() 81 # 打印全部窗口句柄 82 # print(browser.window_handles) 83 # 打印当前窗口句柄 84 print(browser.current_window_handle) 85 # 注意这里点击成员管理之后会自动跳转到一个新窗口打开这个页面 86 # 所以我们需要将窗口句柄切换到这个新窗口 87 browser.switch_to.window(browser.window_handles[1]) 88 # 解释一下browser.switch_to.window是获取当前一共有几个窗口 89 # 这里是2个 90 # browser.switch_to.window这个是指定当前游标切换到哪个窗口 91 # 其实也可以这么写 92 # all_window = browser.switch_to.window返回的是一个列表 93 # browser.switch_to.window(all_window[1]) 94 # 效果是一样的 95 return browser 96 97 98# 开始采集数据 99def start_spider(browser): 100 # 声明一个列表存储字典 101 data_list = [] 102 # 切换句柄之后,我们显示等待窗口出来 103 WebDriverWait(browser, 1000).until( 104 EC.presence_of_all_elements_located( 105 (By.CLASS_NAME, 'my-all-group') 106 ) 107 ) 108 109 # 筛选出我加入的群标签 110 lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[2]/li') 111 if len(lis) == 0: 112 # 如果自己没有创建群,我加入的群就会跑到上面去 113 lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[1]/li') 114 115 # 遍历 116 num = 0 117 while True: 118 try: 119 # 按顺序选择群并获取信息 120 # 先点击该群获取成员信息 121 if lis is None: 122 break 123 if len(lis) == 0: 124 break 125 try: 126 lis[num].click() 127 except BaseException as e: 128 print("读取完毕") 129 break 130 # 显示等待信息加载完成 131 WebDriverWait(browser, 1000).until( 132 EC.presence_of_all_elements_located( 133 (By.CLASS_NAME, 'list') 134 ) 135 ) 136 # 获取该群当前有多少人,后面翻页需要 137 groupMemberNum = eval(browser.find_element_by_id('groupMemberNum').text) 138 # 获取群名称和群号码 139 groupTit = browser.find_element_by_id('groupTit').text 140 141 # 每一次翻页都会刷新21条信息,所以写个循环 142 # 这里加1是因为假如一个群有36人,那么count=1,如果循环的话就不会翻页了 143 # 也就是只能抓到一页的数据,大家可以自己想想其中的流程就知道了 144 count = groupMemberNum // 21 + 1 145 # 这里我只爬取每个群的一部分,如果想爬取全部成员信息 146 # 请注释下面的if语句 147 # if count > 5: 148 # count = 5 149 # 每次循环都进行翻页 150 while count: 151 count -= 1 152 browser.execute_script('document.documentElement.scrollTop=100000') 153 time.sleep(2) 154 time.sleep(3) 155 # 开始获取成员信息 156 trs = browser.find_elements_by_class_name('mb') 157 # 创建一个组存储成员信息 158 qun_numbers_list = [] 159 if trs: 160 # 遍历 161 for tr in trs: 162 tds = tr.find_elements_by_tag_name('td')[2:] 163 if len(tds) == 8: 164 # qq网名 165 qq_name = tds[0].text 166 # 群名称 167 group_name = tds[1].text 168 # qq号 169 qq_number = tds[2].text 170 # 性别 171 gender = tds[3].text 172 # qq年龄 173 qq_year = tds[4].text 174 # 入群时间 175 join_time = tds[5].text 176 # 等级(积分) 177 level = None 178 # 最后发言时间 179 end_time = tds[6].text 180 181 # 声明一个字典存储数据 182 data_dict = {'qq_name': qq_name, 'group_name': group_name, 'qq_number': qq_number, 183 'gender': gender, 'qq_year': qq_year, 'join_time': join_time, 'level': level, 184 'end_time': end_time} 185 qun_numbers_list.append(data_dict) 186 print(data_dict) 187 elif len(tds) == 9: 188 # qq网名 189 qq_name = tds[0].text 190 # 群名称 191 group_name = tds[1].text 192 # qq号 193 qq_number = tds[2].text 194 # 性别 195 gender = tds[3].text 196 # qq年龄 197 qq_year = tds[4].text 198 # 入群时间 199 join_time = tds[5].text 200 # 等级(积分) 201 level = tds[6].text 202 # 最后发言时间 203 end_time = tds[7].text 204 205 # 声明一个字典存储数据 206 data_dict = {'qq_name': qq_name, 'group_name': group_name, 'qq_number': qq_number, 207 'gender': gender, 'qq_year': qq_year, 'join_time': join_time, 'level': level, 208 'end_time': end_time} 209 # data_list.append(data_dict) 210 qun_numbers_list.append(data_dict) 211 print(data_dict) 212 213 browser.find_element_by_id('changeGroup').click() 214 time.sleep(3) 215 WebDriverWait(browser, 1000).until( 216 EC.presence_of_all_elements_located( 217 (By.CLASS_NAME, 'ui-dialog') 218 ) 219 ) 220 lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[2]/li') 221 if len(lis) == 0: 222 # 如果自己没有创建群,我加入的群就会跑到上面去 223 lis = browser.find_elements_by_xpath('.//div[@class="my-all-group"]/ul[1]/li') 224 # 将群成员数据写入json文件 225 p = list(re.findall(r'(.*)\((.*)\)$', groupTit)[0]) 226 g_name = p[0] 227 gid = p[1] 228 file_save_path = os.path.join(save_path, str(gid) + ".json") 229 with open(file_save_path, 'a+', encoding='utf-8') as f: 230 json.dump({"name": g_name, 'gid': gid, "numbers": qun_numbers_list}, f) 231 num += 1 232 except Exception as e: 233 print("发生异常", e) 234 raise Exception(e) 235 236 return data_list 237 238 239def main(): 240 print("======开始抓取======") 241 browser = login_spider() 242 browser = switch_spider(browser) 243 start_spider(browser) 244 print("======抓取完毕======") 245 246if __name__ == '__main__': 247 if test(): 248 main() 249
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Python3:sqlalchemy对mysql数据库操作,非sql语句

Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''

4cast

4castpackageloadcsv.KumarAwanish发布:2020122117:43:04.501348作者:KumarAwanish作者邮箱:awanish00@gmail.com首页: