python爬取qq空间说说
程序员文章站
2022-04-26 08:06:05
...
模块:selenium,pyquery,json,time
使用的是:Chrome
遇到的问题:
- 模拟点击下一页操作,需要换方式。
- 遇到元素在frame,需要进入查找。
对空间的登陆进行分析
进入网址:https://i.qq.com/
说说地址:https://user.qzone.qq.com/{qq}/311
我模拟点击这个头像,也可以点击账号密码登陆,然后填充。
对头像点击右键检查审查元素
我们可以模拟点击这个标签的id进行模拟操作
url = f'https://user.qzone.qq.com/{qq}/311'
browser.get(url)
try:
browser.find_element(By.NAME, 'login_frame') # 发现登陆的frame
except:
raise
else:
try:
browser.switch_to_frame('login_frame') # 发现之后进入login_frame
login = wait.until(EC.element_to_be_clickable(
(By.ID, 'img_out_1290259791'))) # 获取点击按钮 也可以进行输入账号密码
login.click() # 进行点击
except Exception as e:
raise
time.sleep(2)
在模拟登陆的时候:
- 直接寻找这个By.ID,img_out_1290259791是查找不到的,因为他在frame里面,所以browser.find_element(By.NAME, ‘login_frame’)进行判断发现。
- 然后再进入 browser.switch_to_frame(‘login_frame’)
- 然后才是模拟点击登陆
对说说进行分析
思路是:首先寻找说说有几页,然后在进行每页的跳转
这里就是说说的内容,发现这里也是一个frame,所以要进入,然后判断说说有几页。
browser.switch_to_frame('app_canvas_frame') # 进入switch_to_frame
page_last = wait.until(EC.presence_of_element_located(
(By.CSS_SELECTOR, '#pager_last_0 > span'))).text # 最后一页
return int(page_last)
对说说内容进行分析
def get_page_text(n):
try:
doc = pq(browser.page_source) # 获取页面的html
items = doc('#msgList > li.feed').items() # 获取所有的说说
for item in items: # 对说说进行分开
yield {
'time': item.find('div.box.bgr3 > div.ft > div.info > .c_tx3 > .c_tx').text(),
'text': item.find('.content').text().lstrip('♡\n')
}
text = wait.until(EC.presence_of_element_located((By.ID, f'pager_go_{n-1}'))) # 获取跳转页的输入框
text.send_keys(n+1) # 输入下一页
text.send_keys(Keys.ENTER) #进行确定
except:
browser.close()
一开始模拟的点击下一页来进行爬去,但是遇到的问题是,
- 有的时候模拟点击的时候页面没有加载完毕,所以模拟点击的位置不在下一页
- 点击下一页了,没有跳转
所以换取了思路,进行跳转页的点击,知道了这一点以后,遇到爬页面的点击就不要模拟点击下一页了。
爬取的格式:
{"time": "12:42", "text": "一个男生如果真的爱你 无论多忙 都会腾出时间来陪你 他舍不得你胡思乱想 {uin:5289224,nick:查看全文,who:1}"}
{"time": "6:00", "text": " 我发现女孩子很容易被感动 喜欢的人说一句稍微宠溺一点的话 就开心的想把脸埋进被子里闷闷的笑出声 笑完又觉得丢脸 明明一大把年纪 还像个没爱过人的少女"}
{"time": "昨天23:07", "text": " 如果想我了 就抱抱空气吧 毕竟本可爱无处不在"}
{"time": "昨天23:07", "text": ""}
{"time": "昨天20:09", "text": "\"\"\" 他本是小小子国的质子,身份卑微,但是没关系。她喜 今夜,是她的新婚夜。 她披着凤冠霞帔,紧张又害怕。 最后她听到宫女们的声音,唤了一声驸马爷。 她知道,他来了,她的如意郎君魏君羡。欢他,喜欢这匹野马,一步步提携,最终胜任皇宫禁*统领,这才有资格成为她的驸马。 她从盖头的边缘看到了他的靴子,驻足在面前,却迟迟没有揭开盖头。 她正纳闷,没想到他吹熄了蜡烛,直接将她Tui到在chuang上,随后是si&che她的喜服。 嘶啦一声,她骤然一凉。 “君羡……”"}
{"time": "昨天13:47", "text": " 祝你喜欢的人恰巧也喜欢你 祝你每次考试都能有进步 祝你在下雨天时路上的空车都不拒载 祝你做过的美梦都不会忘记 祝你的心情永远像周五的下午 祝你永远活的像个孩子"}
完整的代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from pyquery import PyQuery as pq
import time
import json
options = webdriver.ChromeOptions()
# 设置无图模式
prefs = {
'profile.default_content_setting_values': {
'images': 2
}
}
options.add_argument('--headless') # 浏览器隐藏
options.add_argument('--disable-gpu')
options.add_experimental_option('prefs', prefs) #设置无图模式
browser = webdriver.Chrome(chrome_options=options)
wait = WebDriverWait(browser, 5)
def get_last_page(qq):
try:
url = f'https://user.qzone.qq.com/{qq}/311'
browser.get(url)
try:
browser.find_element(By.NAME, 'login_frame') # 发现登陆的frame
except:
raise
else:
try:
browser.switch_to_frame('login_frame') # 发现之后进入login_frame
login = wait.until(EC.element_to_be_clickable(
(By.ID, 'img_out_1290259791'))) # 获取点击按钮 也可以进行输入账号密码
login.click() # 进行点击
except Exception as e:
raise
time.sleep(2)
browser.switch_to_frame('app_canvas_frame') # 进入switch_to_frame
page_last = wait.until(EC.presence_of_element_located(
(By.CSS_SELECTOR, '#pager_last_0 > span'))).text # 最后一页
return int(page_last)
except Exception:
get_last_page(qq)
def get_page_text(n):
try:
doc = pq(browser.page_source) # 获取页面的html
items = doc('#msgList > li.feed').items() # 获取所有的说说
for item in items: # 对说说进行分开
yield {
'time': item.find('div.box.bgr3 > div.ft > div.info > .c_tx3 > .c_tx').text(),
'text': item.find('.content').text().lstrip('♡\n')
}
text = wait.until(EC.presence_of_element_located((By.ID, f'pager_go_{n-1}'))) # 获取跳转页的输入框
text.send_keys(n+1) # 输入下一页
text.send_keys(Keys.ENTER) #进行确定
except:
browser.close()
def write_page(page):
with open('qq.txt', 'a', encoding='utf-8') as f:
for page in get_page_text(page):
f.write(json.dumps(page, ensure_ascii=False) + '\n') # 将dict转换为json格式进行保存
if __name__ == '__main__':
page_last = get_last_page('qq')
for i in range(1, page_last+1):
write_page(i)
browser.close()
上一篇: Scrapy爬虫笔记——1
下一篇: 我和Git有个约会(一)基础命令篇