QQ空间说说爬虫
QQ空间说说爬虫
闲来无事,写了一个QQ空间的爬虫,主要是爬取以前的说说,然后生成词云。
这次采用的主要模块是selenium,这是一个模拟浏览器的模块,一开始我不想用这个模块写的,但是后面分析的时候,发现QQ空间的数据加密有点复杂,也没有找到好用的接口,正好又有在学习这个模块,然后就直接用这个模块获取了,这个模块的好处就是不用去纠结传输的过程是如何加密的。
selenium 简介:Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本
思路
爬取数据模块
通过selenium模块来模拟浏览器登录QQ空间的操作,进入到说说页面,获取说说的总数目和总页数,从最后一页最后一条,即用户的第一条说说开始爬取,存入MongoDB,重复操作直到爬完最后一条。
词云模块
从数据库读取数据,设置图片(可选),生成词云。
整体思路不难,只是有点地方需要注意下:
- 在进入到QQ空间的登录页面的时候
https://i.qq.com/先给出的是一个扫码登录的窗口

需要先点击一下『帐号密码登录』才可以进入到输入的界面
还有个比较恶心的地方就是,一开始登录进去的是『个人中心』的界面,那个从个人中心页面选择说说的按钮我一直点击不了,也可能是对JS不太了解的原因,后面直接通过URL跳转到『我的主页』,因为浏览器自带cookie的原因,直接跳转过去是成功的。
我不懂其他账号会不会有这种情况,就是有时候他会弹出黄砖过期的广告,如果不点击的话,就无法进入到下一步的操作,有时候又不弹,所以我这边写了个等待十秒,如果有的话,就关闭,没有就直接进入下一步。
还有一个地方,因为进入到『说说』板块的时候,第一页显示你最近发的说说,因为我想从第一条开始爬,所以跳转到最后一页,然后从最后一条一直往上爬,就可以爬取到第一条说说到最后一条说说,这里出现的问题是,一开始我只是
time.sleep(1),导致后面爬取的数据是从第一页先爬,然后再爬最后一页。一开始我调试的时候,没有注意到是时间的问题,在解决这个问题的时候,还花了点时间,后面只需把time.sleep给延长点就解决了,很奇怪的是,明明显示的是更新后的页面,传送过去的页面并没有是最新的,可能是缓存机制。
剩下的也就没有什么难度了,都是些基本操作,这次的爬虫为了实现模拟是人在使用浏览器进行操作,整体的延迟等待还是会有点多的,不需要的可以自行设置延时时间。
代码
代码如下,该注释的都注释了,基本都能看得懂,也都是些很基础的代码。
# -*-coding:utf-8-*-
# Author: AnswerW3I
# version:3.6.3
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
import numpy
from PIL import Image
import time
from bs4 import BeautifulSoup
import matplotlib.pyplot as plt
from wordcloud import WordCloud
import jieba
import pymongo
class QZone_Spider(object):
def __init__(self, url):
self.url = url
# self.Browser = webdriver.Chrome() # 可以看到程序的执行流程
self.Browser = self._browser() # 无头模式,看不到流程,提高程序的效率
self.Browser.get(url)
self.wait = WebDriverWait(self.Browser, 10) # 显示等待,等待网页加载
self.talks = 1 # 从第一条说说开始计数
self.client = pymongo.MongoClient('localhost', port=27017) # 数据库连接
self.db = self.client.test
self.collection = self.db.QQZone
def _browser(self):
"""
:return: 返回一个无头浏览器,禁止加载图片
"""
chrome_options = Options()
prefs = {'profile.default_content_setting_values':{
'images':2
}
} # 禁止浏览器加载图片,提高浏览器运行速度
chrome_options.add_experimental_option('prefs', prefs)
chrome_options.add_argument('window-size=1700x938') # 设置窗口大小,这个很重要,不然无头模式下无法加载页面,会报错
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
Browser = webdriver.Chrome(chrome_options=chrome_options)
Browser.set_window_size(width=1700, height=1000)
return Browser
def _login(self, user, password):
"""
登录用户
"""
self.Browser.switch_to.frame('login_frame')
time.sleep(1)
login_button = self.Browser.find_element(By.ID, 'switcher_plogin')
login_button.click()
time.sleep(1)
input_name = self.Browser.find_element(By.ID, 'u')
input_password = self.Browser.find_element(By.ID, 'p')
button = self.Browser.find_element(By.ID, 'login_button')
input_name.send_keys(user)
time.sleep(1)
input_password.send_keys(password)
time.sleep(1)
button.click()
time.sleep(5)
self.talks_url = "https://user.qzone.qq.com/" + user + "/main" # qq空间主页
def _get_talks(self, url):
"""
获取说说内容
"""
self.Browser.get(url)
time.sleep(10)
self._close_yellow_page(self.Browser.page_source)
talks_button = self.Browser.find_element(By.ID, 'QM_Profile_Mood_Cnt')
self.talks_num = talks_button.text
print("talks:"+ self.talks_num)
talks_button.click()
time.sleep(5)
self.Browser.switch_to.frame('app_canvas_frame') # 进入到说说的frame
self.pages = self._get_all_pages()
for page in range(self.pages, 0, -1): # 从最后一页开始,也就是第一条说说开始爬取
print("开始爬取第{0}页".format(page))
# 获取当前页面的说说
self._get_page(page=page)
print("第{0}页爬取完毕".format(page))
time.sleep(5)
print("OK!")
def _close_yellow_page(self, html):
# 关闭黄砖广告
soup = BeautifulSoup(html, 'lxml')
page = soup.find_all(id="dialog_main_1")
if page != []:
self.Browser.find_element(By.CLASS_NAME, 'qz_dialog_btn_close').click()
def _says(self, html):
"""
爬取说说
:param html: 当前说说的html页面
"""
soup = BeautifulSoup(html, 'lxml')
print("start with {0}".format(self.Browser.find_element(By.CLASS_NAME, 'mod_pagenav_main').find_element(By.CLASS_NAME, 'current').text))
says = soup.select('.feed')
for item in says[::-1]: # 从说说列表的下面开始爬取
print("第{0}条爬取成功".format(self.talks))
self.talks = self.talks + 1
yield {
"say": item.select('.content')[0].text, # 说说内容
"date": item.select('.ft .goDetail')[0]['title'] # 说说发布的时间
}
def _get_all_pages(self):
"""
:return: 说说总页数
"""
return int(self.Browser.find_element(By.ID, 'pager_last_0').text)
def _get_page(self, page):
change_page = self.Browser.find_element(By.CLASS_NAME, 'mod_pagenav_option').find_element(By.CLASS_NAME, 'textinput')
change_page_button = self.Browser.find_element(By.CLASS_NAME, 'mod_pagenav_option').find_element(By.CLASS_NAME, 'bt_tx2')
change_page.send_keys(page)
time.sleep(1)
change_page_button.click() # 进入下一页
self.wait = WebDriverWait(self.Browser, 10)
print(self.Browser.find_element(By.CLASS_NAME, 'mod_pagenav_main').find_element(By.CLASS_NAME, 'current').text)
time.sleep(10) # 这个很重要,不然加载不出新的页面...
for item in self._says(self.Browser.page_source):
self._save(item)
# print(item)
def _save(self, data):
"""
保存到MongDB里面
"""
self.collection.insert(data)
class FenCI(object):
def __init__(self):
self.client = pymongo.MongoClient("localhost", port=27017)
self.db = self.client.test
self.collection = self.db.QQZone
def _get_words(self):
words = ""
for item in self.collection.find({}):
for i in self._cut_words(item['say']):
words = words + i + " "
return words
def _cut_words(self, data):
for item in jieba.cut(data, cut_all=False):
try:
yield item
except Exception as err:
# 这里有时候会爬取到emoji表情,导致编码读取的时候会报错,这里直接pass掉
pass
def _wordColud(self):
"""
显示词云
"""
world_picture = numpy.array(Image.open("C:/Users/Desktop/img.jpg")) # 加载图片的路径,可选项,不需要图片的话,把下面WorCloud下的mask去掉。
wl_space_split = self._get_words()# 获取生成图文的文字
font = r'C:\Windows\Fonts\simfang.ttf'
my_wordcloud = WordCloud(background_color="white", collocations=False, font_path=font, width=1400, height=1400, margin=2, mask=world_picture).generate(wl_space_split) # 设置图片大小
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()
plt.savefig('QQZone.png') # 保存图片
def main():
url = "https://i.qq.com/"
Spider = QZone_Spider(url)
User = input("User:")
Password = input("Password:")
Spider._login(user=User, password=Password)
Spider._get_talks(Spider.talks_url)
# 显示词云
Picture = FenCI()
Picture._wordColud()
if __name__ =="__main__":
main()
后记
感觉博客还是得多写,不然感觉文章格式都成一个问题。
这篇文章本该前几天就发了的...一直拖拖到现在...然后最近这段时间也有点迷茫,希望接下来能好好调整一下
QQ空间说说爬虫的更多相关文章
- QQ空间动态爬虫
作者:虚静 链接:https://zhuanlan.zhihu.com/p/24656161 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 先说明几件事: 题目的意 ...
- qq空间爬取
QQ_spider github传送门 QQ空间spider总结 花了将近3天吧,完成了低配版qq空间的爬虫,终于能上线刚一波了,还是蛮期待的. 流程很简单,模拟登录 ==>采集==>保存 ...
- QQ空间爬虫最新分享,一天 400 万条数据(附代码地址)
http://mp.weixin.qq.com/s?__biz=MzAxMjUyNDQ5OA==&mid=2653552228&idx=1&sn=e476bf23556406c ...
- Python爬虫实战:使用Selenium抓取QQ空间好友说说
前面我们接触到的,都是使用requests+BeautifulSoup组合对静态网页进行请求和数据解析,若是JS生成的内容,也介绍了通过寻找API借口来获取数据. 但是有的时候,网页数据由JS生成,A ...
- QQ空间爬虫--获取好友信息
QQ空间网页版:https://user.qzone.qq.com/ 登陆后,进入设置,有一个权限设置,设置“谁能看我的空间”为好友可见,然后构造爬虫. (1)获取Cookie 两种方式: 第一种:通 ...
- QQ空间动态内容,好友信息,点赞爬虫脚本
一.安装基础的软件包: 1.准备好火狐浏览器,并下载geckodriver,将geckodriver加入到环境变量:下载geckodriver的地址:https://pan.baidu.com/s/1 ...
- Python 爬虫监控女神的QQ空间新的说说,实现邮箱发送
主要实现的功能就是:监控女神的 QQ空间,一旦女神发布新的说说,你的邮箱马上就会收到说说内容,是不是想了解一下 先看看代码运行效果图: PS:只有你有一台云服务器你就可以把程序24h运行起来 直接上代 ...
- Python 爬虫监控女神的QQ空间新的说说,实现秒赞,并发送说说内容到你的邮箱
这个文章主要是在前一篇文章上新增了说说秒赞的功能 前一篇文章可以了解一下 那么,这次主要功能就是 监控女神的 QQ空间,一旦女神发布新的说说,马上点赞,你的邮箱马上就会收到说说内容,是不是想了解一下 ...
- Java版 QQ空间自动登录无需拷贝cookie一天抓取30WQQ说说数据&流程分析
QQ空间说说抓取难度比较大,花了一个星期才研究清楚! 代码请移步到GitHub GitHub地址:https://github.com/20100507/Qzone [没有加入多线程,希望你可以参与进 ...
随机推荐
- windows 下面的grep awk 命令
windows 下面的grep awk 命令 grep 学习了:http://blog.csdn.net/chengfans/article/details/53784936 awk学习了:http: ...
- HDU 4081 Qin Shi Huang's National Road System 最小生成树
点击打开链接题目链接 Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Lim ...
- Android BlueDroid(二):BlueDroid蓝牙开启过程init
关键词:bluedroid initNative enableNative BTIF_TASK BTU_TASKbt_hc_work_thread set_power preload GKI作 ...
- (数据结构整理)NJUPT1054
这一篇博客以一些OJ上的题目为载体,整理一下数据结构.会陆续的更新. .. 我们都知道,数据结构的灵活应用有时能让简化一些题目的解答. 一.栈的应用 1.NJUPT OJ 1054(回文串的推断) 回 ...
- 基于IBM Bluemix的数据缓存应用实例
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:IBM® Data Cache for Bluemix 是快速缓存服务.支持 Web 和 ...
- Swift学习笔记(1):基础部分
目录: 分号 常量和变量 数据类型 数值型类型转换 类型别名 元组 可选类型 API版本检查 分号 Swift并不强制要求你在每条语句的结尾处使用分号( ; ),你也可以按照自己的习惯添加分号.如果在 ...
- IDL build
For Developers > Design Documents > IDL build 目录 1 Steps 2 GYP 3 Performance 3.1 Details ...
- 监控mysqld服务
#!/bin/bash #监控mysqld服务 #telnet 192.168.122.171 3306 | grep Connected | wc -l #远程检查 #num=`netstat -n ...
- 题解 P3372 【【模板】线段树1 】
看了一下题解里的zkw线段树,感觉讲的不是很清楚啊(可能有清楚的但是我没翻到,望大佬勿怪). 决定自己写一篇...希望大家能看明白... zkw线段树是一种优秀的非递归线段树,速度比普通线段树快两道三 ...
- 一款很不错的html转xml工具-Html Agility Pack 实现html转Xml
[转]一款很不错的html转xml工具-Html Agility Pack 之前发个一篇关于实现html转成xml的劣作<实现html转Xml>,受到不少网友的关心.该实现方法是借助htm ...