欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python爬取qq空间说说

程序员文章站 2022-04-26 08:06:05
...

模块:selenium,pyquery,json,time
使用的是:Chrome
遇到的问题:

  1. 模拟点击下一页操作,需要换方式。
  2. 遇到元素在frame,需要进入查找。

对空间的登陆进行分析

进入网址:https://i.qq.com/
说说地址:https://user.qzone.qq.com/{qq}/311
python爬取qq空间说说
我模拟点击这个头像,也可以点击账号密码登陆,然后填充。
对头像点击右键检查审查元素
python爬取qq空间说说
我们可以模拟点击这个标签的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)

在模拟登陆的时候:

  1. 直接寻找这个By.ID,img_out_1290259791是查找不到的,因为他在frame里面,所以browser.find_element(By.NAME, ‘login_frame’)进行判断发现。
  2. 然后再进入 browser.switch_to_frame(‘login_frame’)
  3. 然后才是模拟点击登陆

对说说进行分析

思路是:首先寻找说说有几页,然后在进行每页的跳转

python爬取qq空间说说
这里就是说说的内容,发现这里也是一个frame,所以要进入,然后判断说说有几页。
python爬取qq空间说说

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()

一开始模拟的点击下一页来进行爬去,但是遇到的问题是,

  1. 有的时候模拟点击的时候页面没有加载完毕,所以模拟点击的位置不在下一页
  2. 点击下一页了,没有跳转

所以换取了思路,进行跳转页的点击,知道了这一点以后,遇到爬页面的点击就不要模拟点击下一页了。
爬取的格式:

{"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()

相关标签: Python 空间