前言:非常郁闷,写了第三遍了,无故404
学了五天了,熬夜搞出这份代码,虽然一度卡死几个小时,但结果是好的。
目录
第一部分 Selenium+Chrome爬取空间留言
1.1 使用说明
1.2 代码及注释
1.3 相关问题
第二部分 jieba进行分词
2.1 环境配置
2.2 代码
2.3 注意事项
第三部分 Word Art制作词云
3.1 注意事项
第一部分 Selenium+Chrome爬取空间留言
1.1 使用说明
1.11 条件
使用快捷登陆,要提前登陆QQ
空间装扮不同的话,会出现element not visitable错误建议time.sleep(10)
手动切换到留言板页面
需要输入爬取页面
1.2 代码及注释
# 抓取好友空间留言,需要人工填入页数
# 自己空间需要改下相应element 的名字
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time
# 页面滚动函数(可通用)
def scroll(driver):
driver.execute_script("""
(function () {
var y = document.body.scrollTop;
var step = 100;
window.scroll(0, y);
function f() {
if (y < document.body.scrollHeight) {
y += step;
window.scroll(0, y);
setTimeout(f, 50);
}
else {
window.scroll(0, y);
document.title += "scroll-done";
}
}
setTimeout(f, 1000);
})();
""")
# 模拟登陆以及爬取函数
def crawlSays():
# 打开QQ好友空间
driver = webdriver.Chrome()
driver.get('QQ好友空间网址')
# 等待跳转
time.sleep(2)
# 切换框架
driver.switch_to_frame('login_frame')
# 使用快捷方式模拟登陆,需要先登陆电脑QQ
driver.find_element_by_id('img_out_自己QQ号').click()
time.sleep(4)
# 建议以下两行代码,使用手动切换到留言板页面,避免因空间布局不同而报错
# 同时,上面的休眠时间可以适当增加,保证自己手动操作及时
# 当然,也可以改写这两行代码
# 查看亲密度,点击我确定
driver.find_element_by_class_name('btn-fs-sure').click()
time.sleep(5)
elem_says = driver.find_element_by_css_selector("a[tabindex='1'][title='留言板']")
elem_says.click()
# 切换到默认页面
driver.switch_to.default_content()
page=0 # 需要爬取的页数
number=0 # 留言总个数
NoneName=0 # 留言中匿名的个数只可自己查看)
# 创建分别保存姓名,留言的txt文件
with open('Says.txt','w') as f ,open('Names.txt','w') as f1:
while(page<需要爬取的页数-1):
time.sleep(1)
# 页面滑到最低端,否则下一页没有显示,会报错
scroll(driver)
time.sleep(2)
# 转换框架
driver.switch_to_frame('app_canvas_frame')
# 读取网页
html = driver.page_source
soup = BeautifulSoup(html,'lxml')
sayLis=soup.find_all('li',class_="bor3 hide_comment_tip")
try:
for sayLi in sayLis:
try:
name = sayLi.find(class_="c_tx q_namecard")["title"]
say = sayLi.find('tbody').find('tr')
f1.write(str(name) + '\n')
# 判断留言是否是图片,图片则不保存
# 可以添加保存图片的代码
if (say.string != None):
f.write(say.string + '\n')
number += 1
except Exception:
# 计算私密留言的个数(好友不可见)
print("None Name")
NoneName+=1
print(number)
except Exception:
print('Something is wrong')
page += 1
# 点击下一页
# 使用.send_keys('\ n')来模拟点击并解决Chrome中的问题,显示的还是本页
# 最终模拟键盘点击send_keys(Keys.ENTER),成功
driver.find_element_by_css_selector('[onclick="QZBlog.Util.PageIndexManager.goPage(1);return false;"]').send_keys(Keys.ENTER)
driver.switch_to.default_content()
print('page '+str(page)+' has print')
print('Sum of says is '+str(number)+' , None name are '+str(NoneName))
print('That is all')
time.sleep(10)
crawlSays()
1.3 相关问题
1.3.1 点击下一页的几种操作及报错原因(可以略过)
参考Debugging “Element is not clickable at point” error
# 报错AttributeError: module 'selenium.webdriver.support.expected_conditions' has no attribute 'invisibilityOfElementLocated'
elem_next = driver.find_element_by_css_selector('[onclick="QZBlog.Util.PageIndexManager.goPage(1);return false;"]')
wait = WebDriverWait(driver, 2)
wait.until(EC.invisibilityOfElementLocated(elem_next))
elem_next.click()
# </iframe> is not clickable at point (59, 0). Other element would receive the click: <a class="logo" href="//user.qzone.qq.com/1509321148/" title="...">QQ空间</a>
elem_next = driver.find_element_by_css_selector('[onclick="QZBlog.Util.PageIndexManager.goPage(1);return false;"]')
action = ActionChains(driver)
action.move_to_element(elem_next).click().perform()
# 报错selenium.common.exceptions.ElementNotVisibleException: Message: element not visible
driver.find_element_by_class_name('c_tx ').click()
# 报错 selenium.common.exceptions.WebDriverException: Message: unknown error: Element <iframe>.......
</iframe> is not clickable at point (59, 0). Other element would receive the click: <a class="logo" href="//user.qzone.qq.com/1509321148/" title="...">QQ空间</a>
elem_next = driver.find_element_by_css_selector('.textinput')
action = ActionChains(driver)
action.move_to_element(elem_next).click().send_keys(Keys.BACK_SPACE).send_keys(str(page)).perform()
driver.find_element_by_class_name('bt_tx2').click()
1.3.2 点击下一页的解决
# 使用.send_keys('\ n')来模拟点击并解决Chrome中的问题,显示的还是本页
# 最终模拟键盘点击.send_keys(Keys.ENTER),成功
driver.find_element_by_css_selector('[onclick="QZBlog.Util.PageIndexManager.goPage(1);return false;"]').send_keys(Keys.ENTER)
当然还有很多思路光页面上的操作都有三种,都可以进行模拟,但是要注意对应,小心报错,有一种简单的思路可以参考思路
1.3.3遐想
自此,是想爬什么,爬什么,只需要模拟即可,不会模拟的直接sleep来手动操作。
当然,挡路的是各种细节的处理,主要参考Stack Overflow,直接搜索报错原因,然后查看评论,总会解决的
然而爬虫手段还比较低劣,不能大量使用,效率还低
往后呢,可以采用PhantomJS,还有多进程,分布式,框架的使用,学习保存方法,以及云服务器
第二部分 jieba进行分词
2.1 环境配置
参考在Python里安装Jieba中文分词组件
2.2 代码
import jieba.analyse
# 爬取的文件
path = 'D:\Python Study\ZhouQzoneSays\says.txt'
file_in = open(path, 'r')
content = file_in.read()
try:
#打开中文停词表 需要把停词表 格式改成utf-8
jieba.analyse.set_stop_words('D:\Python Study\crawl\ChineseSplitWords.txt')
tags = jieba.analyse.extract_tags(content, topK=100, withWeight=True)
for v, n in tags:
#权重是小数,为了凑整,乘了一万
print (v + '\t' + str(int(n * 10000)))
finally:
file_in.close()
2.3 注意事项:
①下载与python匹配的jieba压缩包
②使用半自动安装(切换到jieba所在文件夹),直接 pip install jieba
可能出错
③最重要的是,停用词表保存为 UTF-8 格式,否者报错
第三部分 Word Art制作词云
用jieba分词提取关键词做漂亮的词云
3.1 注意事项:
①需要自己导入字体,可以在电脑开始那输入字体,会出现电脑已有的的字体,然后复制出来,粘贴到一个地方,就可以使用了
无图无真相,展示一下:
爬取的留言,效率比较低,测试,100页留言,基本得5分钟左右
后续可以改进,可以不用Chrome,改为PhantomJS,同时,删除一些不必要的休眠时间
制作的词云,形状,图片,字体,颜色可以搭配