实战项目三:爬取QQ群中的人员信息
发布日期:2021-07-01 04:21:42
浏览次数:36
分类:技术文章
本文共 5505 字,大约阅读时间需要 18 分钟。
文章目录
----------
一、selenium简介
我们模拟登陆用的是selenium库,selenium是一个自动化测试工具,在爬虫中通常用来进行模拟登陆。
(一)实例说明
from selenium import webdriver driver = webdriver.Chrome()driver.get('http://www.baidu.com/')
代码功能:1.打开谷歌浏览器,2.自动输入百度网址并打开百度
如果程序执行错误,浏览器没有打开,那么应该是没有装 Chrome 浏览器或者 Chrome 驱动没有配置在环境变量里。下载驱动,然后将驱动文件路径配置在环境变量即可。
(二)元素定位方式
单个元素选取:
find_element_by_idfind_element_by_namefind_element_by_xpathfind_element_by_link_textfind_element_by_partial_link_textfind_element_by_tag_namefind_element_by_class_namefind_element_by_css_selector
多个元素选取:
find_elements_by_namefind_elements_by_xpathfind_elements_by_link_textfind_elements_by_partial_link_textfind_elements_by_tag_namefind_elements_by_class_namefind_elements_by_css_selector
代码示例:
#获取网页中的h1标签h1 = driver.find_element_by_name("h1")#获取网页中所有的h1标签h1_list = driver.find_elements_by_name("h1")
(三)实现滚动条自动下拉
代码展示:
#将滚动条移动到页面的底部js="var q=document.documentElement.scrollTop=100000" driver.execute_script(js)
二、Xpath简介
XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。结构关系包括 父、子、兄弟、先辈、后代等。
(一)语法:
表达式 | 功能描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
… | 选取当前节点的父节点。 |
@ | 选取属性。 |
通配符 | 描述 |
---|---|
* | 匹配任何元素节点。 |
@* | 匹配任何属性节点。 |
node() | 匹配任何类型的节点。 |
(二)实例:
路径表达式 | 结果 |
---|---|
bookstore | 选取 bookstore 元素的所有子节点。 |
/bookstore | 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
路径表达式 | 结果 |
---|---|
/bookstore/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
更多语法知识参考:
代码实例:
#获取 class 为 bold 的标签名result = html.xpath('//*[@class="bold"]')
三、定义一个爬虫类
(一)导入包
import timefrom selenium import webdriver
(二)初始化类
class qqGroupSpider(): ''' Q群爬虫类 ''' def __init__(self, driver,qq,passwd,qqgroup): ''' 初始化根据用户信息登录到Q群管理界面 :param driver: :param qq: :param passwd: :param qqgroup: :param writefile: ''' url = "https://qun.qq.com/member.html#gid={}".format(qqgroup) self.driver=driver driver.delete_all_cookies() driver.get(url) time.sleep(1) driver.switch_to.frame("login_frame") # 进入登录iframe time.sleep(1) change = driver.find_element_by_id("switcher_plogin") change.click() driver.find_element_by_id('u').clear() # 选择用户名框 driver.find_element_by_id('u').send_keys(qq) driver.find_element_by_id('p').clear() driver.find_element_by_id('p').send_keys(passwd) driver.find_element_by_class_name("login_button").click() time.sleep(1)
(三)滚动条自动下拉
def scroll_foot(self,driver): ''' 控制屏幕向下滚动到底部 :param driver: :return: ''' js = "var q=document.documentElement.scrollTop=100000" return driver.execute_script(js)
(四)获取Tbody标签的列表
def getTbodyList(self, driver): print("getTbodyList()函数运行过") return driver.find_elements_by_xpath('//div[@class="group-memeber"]//tbody[contains(@class,"list")]')
(五)解析Tbody标签
def parseTbody(self, html): ''' 解析tbody里面的内容,一个tbody里面有多个成员, 解析完成后,返回成员基本情况的列表 :param html: :return: ''' # selector = etree.HTML(html) print("parseTbody()函数运行过") memberLists = [] for each in html: memberList = each.find_elements_by_xpath('tr[contains(@class,"mb mb")]') memberLists += memberList print("memberLists长度为:{}".format(len(memberLists))) memberLists_data = [] for each in memberLists: memberLists_data.append(self.parseMember(each)) return memberLists_data
(六)提取Tbody标签中每个群员的信息
def parseMember(self, mb): ''' 解析每个人各项描述,以逗号隔开,返回一个成员的基本情况 :param mb: :return: ''' print("parseMember()函数运行过") td = mb.find_elements_by_xpath('td') print("td长度为:{}".format(len(td))) qId = td[1].text.strip() nickName = td[2].find_element_by_xpath('span').text.strip() card = td[3].find_element_by_xpath('span').text.strip() qq = td[4].text.strip() sex = td[5].text.strip() qqAge = td[6].text.strip() joinTime = td[7].text.strip() lastTime = td[8].text.strip() a = (qId + "|" + qq + "|" + nickName + "|" + card + "|" + sex + "|" + qqAge + "|" + joinTime + "|" + lastTime) print(a) return a
(七)将提取到群员的信息写入文件
def parseAndWrite(self, tbody): ''' 解析HTML中的tbody,解析完成后写入到本地文件 :param tbody: :return: ''' print("parseAndWrite()函数运行过") memberList = self.parseTbody(tbody) with open("1607.csv", 'a+', encoding="utf-8") as f: for each in memberList: f.write(str(each)+"\n")
四、主函数
def main(): qq = "你的QQ账号" passwd = "你的QQ密码" qqgroup = "想要爬取的QQ群群号" driver = webdriver.Chrome() spider=qqGroupSpider(driver,qq,passwd,qqgroup) time.sleep(10) # 找到QQ群的人数 qqNum = int(driver.find_element_by_xpath('//*[@id="groupMemberNum"]').text.strip()) print("QQ群人数为:"+str(qqNum)) curren_qq_num=0 prelen=0 while curren_qq_num != qqNum: curren_qq_num=len(driver.find_elements_by_xpath('//*[@id="groupMember"]//td[contains(@class,"td-no")]')) #不停的向下滚动屏幕,直到底部 spider.scroll_foot(driver) #每次滚动休息1秒 time.sleep(1) tlist = spider.getTbodyList(driver) spider.parseAndWrite(tlist[prelen:]) prelen = len(tlist)#更新tbody列表的长度 driver.quit()if __name__ == '__main__': main()
转载地址:https://mtyjkh.blog.csdn.net/article/details/82963395 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2024年04月19日 04时38分12秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【redis6.0.6】redis源码慢慢学,慢慢看 -- 第五天:adlist
2019-04-27
别抖,OK? 操作系统抖动现象、网络抖动与延迟、函数抖动之防抖与节流,串讲
2019-04-27
通过域名获取主机IP -- struct addrinfo
2019-04-27
【C++】算法集锦(8):从两数和问题拓展到一百数和问题
2019-04-27
【C++】算法集锦(9):背包问题
2019-04-27
【C++】算法集锦(10)通俗讲kmp算法
2019-04-27
【C++】算法集锦(12):高楼扔鸡蛋
2019-04-27
【图解】拥塞控制
2019-04-27
线程上下文切换
2019-04-27
什么是服务熔断?
2019-04-27
服务器压力过大?CPU打满?我来帮你快速检查Linux服务器性能
2019-04-27
C++面经总结之《Effective C++》(一)
2019-04-27
C++面经总结之《Effective C++》(二)
2019-04-27
这是什么“虎狼之词”啊!!!程序员的健康问题,看一线老中医怎么说!!!
2019-04-27
打开我的收藏夹 -- Python数据分析杂谈
2019-04-27
上手Pandas,带你玩转数据(1)-- 实例详解pandas数据结构
2019-04-27
上手Pandas,带你玩转数据(2)-- 使用pandas从多种文件中读取数据
2019-04-27
上手Pandas,带你玩转数据(3)-- pandas数据存入文件
2019-04-27
爬虫遇上不让右击、不让F12的网站,该怎么办?
2019-04-27