【爬虫】用selenium登陆推特并爬取用户历史推文

这篇具有很好参考价值的文章主要介绍了【爬虫】用selenium登陆推特并爬取用户历史推文。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

做rumor detection 用到了twitter15和twitter16数据集,里边只给了推文id和评论者的uid,想要爬取其他数据就只能自己动手。
我需要爬取推文评论用户在评论时间点前两个月的历史推文,然而这两个数据集都太老了,里边的数据都是13-14年的,所以用twitter API无法获取到(因为官方API只能爬用户最近3000条历史推文),因此只能用推特的搜索API来爬数据。
这篇文章给出了用推特搜索api的爬取过程,但是万恶的马斯克限制了搜索API的使用权限,现在只能登陆后才能调用搜索API了。
之前有过一段时间selenium使用经验,所以打算用selenium模拟登陆后来爬取数据。因为数据集中推文很多,大概两千条,然后底下的评论平均有五个用户吧,所以一共要爬取差不多一万个用户的历史推文,规模还是蛮大的。因此在这个过程中还用到了多进程来加快爬取的速度。

获取cookies

用了selenium来模拟登陆过程,自动输入twitter账号和密码。

import time
from selenium import webdriver
twi_username = "username"
twi_keyword = "password"
browser = webdriver.Chrome()
browser.get(r'https://twitter.com/i/flow/login')
#这里睡几秒,等待页面加载。
time.sleep(5)
browser.find_element("xpath","//*[@id=\"layers\"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[5]/label/div/div[2]/div/input").send_keys(twi_username)
time.sleep(3)
browser.find_element("xpath","//*[@id=\"layers\"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div/div/div/div[6]/div").click()
time.sleep(2)
browser.find_element("xpath","//*[@id=\"layers\"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div/div[3]/div/label/div/div[2]/div[1]/input").send_keys(twi_keyword)
browser.find_element("xpath","//*[@id=\"layers\"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[2]/div/div[1]/div/div/div/div/span/span").click()
time.sleep(2)
#使用这个函数可以导出browser的cookies
savedCookies = browser.get_cookies()
print(savedCookies)

savedCookies 是一个词典,将cookies打印出来后复制一下,之后会用到。

应用cookies

推特现在对搜索作出了一些限制,首先就是得登陆后才能用搜索,其次就是当搜索次数过多后,会禁用一段时间搜索功能。
为了加快爬取进度,可以用多个推特账号来登陆。
这里参考了这篇文章
这个函数返回了一个浏览器

def init_browser(i):
	#因为用了多线程,i表示线程编号
	
    savedCookies1=[{}]
    savedCookies2=[{}]
    
	#两个推特账号,对应俩cookies
    savedCookies_list=[savedCookies1,savedCookies3]
	#通过线程编号来分配cookies
    savedCookies=savedCookies_list[i%2]

	#d和co俩变量是为了之后获取浏览器日志
    co = webdriver.chrome.options.Options()
    co.add_experimental_option('w3c',False)
    d = webdriver.common.desired_capabilities.DesiredCapabilities.CHROME
    d['loggingPrefs']={'performance':'ALL'}
    d["goog:loggingPrefs"] = {"performance": "ALL"}
    browser = webdriver.Chrome(desired_capabilities=d,options=co)

    browser.get(r'https://twitter.com/i/flow/login')
    time.sleep(1)
    browser.delete_all_cookies()
    for cookie in savedCookies:
        for k in {'name', 'value', 'domain', 'path', 'expiry'}:
            # cookie.keys()属于'dict_keys'类,通过list将它转化为列表
            if k not in list(cookie.keys()):
                # saveCookies中的第一个元素,由于记录的是登录前的状态,所以它没有'expiry'的键名,我们给它增加
                if k == 'expiry':
                    t = time.time()
                    cookie[k] = int(t)  # 时间戳s
        browser.add_cookie({k: cookie[k] for k in {'name', 'value', 'domain', 'path', 'expiry'}})
    return browser

使用搜索API爬取推文

推特高级搜索里边有很多字段,选定字段后可以搜到相关推文。
这里参考了这篇文章的思路,通过adative.json可以得到推文信息,但是那位大佬用request库来搞的,我不是很了解orz。用selenium做的话,可以通过获取浏览器日志来实现,参考了这篇文章

在长时间爬数据时,可能会遇到一些问题:

  • 网不好,所以可能还在加载,所以用了is_search_loading(driver)函数来检测网页是否还在加载
  • 被推特限制搜索了,用到is_search_loading(driver)函数

这俩函数原理很简单,就是判断有没有出现相关的元素,如果出现了,就返回True。
如果

def is_search_limitted(driver):
    #调用该函数时页面可能没有加载完毕,睡个2秒
    time.sleep(2)
    try:
        driver.find_element("xpath",
"/html/body/div[1]/div/div/div[2]/main/div/div/div/div/div/div[3]/div/div/div[2]/div/span/span")

        return True
    except:
        return False
def is_search_loading(driver):
    try:
        time.sleep(2)
        driver.find_element("xpath","/html/body/div[1]/div/div/div[2]/main/div/div/div/div/div/div[1]/div[1]/div[1]/div/div/div/div/div[2]/div[2]/div/div/div/svg")
        return True
    except:
        return False
    return
def scrollUntilLoaded(driver):
    last_height = driver.execute_script("return document.body.scrollHeight")
    while is_search_loading(driver):
        time.sleep(2)
    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(2)
        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height:
            break
        last_height = new_height
def scrapUserTweets(browser,username,since_time,until_time):
    # username = ""
    # since_time = "2019-08-22"
    # until_time = "2019-09-22"
    browser.get(
        fr'https://twitter.com/search?q=from%3A{username}%20until%3A{until_time}%20since%3A{since_time}%20-filter%3Alinks%20-filter%3Areplies&src=typed_query')
    time.sleep(2)
    sleep_time = 60
    #如果搜索限制了,就睡一分钟
    while is_search_limitted(browser):
    
        print("*****search limitted, sleep {} seconds".format(sleep_time))
        time.sleep(sleep_time)

        browser.get(
            fr'https://twitter.com/search?q=from%3A{username}%20until%3A{until_time}%20since%3A{since_time}%20-filter%3Alinks%20-filter%3Areplies&src=typed_query')

    scrollUntilLoaded(browser)
    #获取浏览器日志
    logs = browser.get_log("performance")

    tweets = []

    for log in logs:
        logjson = json.loads(log["message"])["message"]
        if logjson['method'] == 'Network.responseReceived':
            params = logjson['params']
            try:
                # 找到那啥adaptive.json玩意
                requestUrl = params['response']['url']
                if "adaptive.json" in requestUrl:

                    requestId = params['requestId']
                    response_body = browser.execute_cdp_cmd('Network.getResponseBody', {'requestId': requestId})
                    _content = json.loads(response_body["body"])
                    tweets_set = _content['globalObjects']['tweets']
                    for w in tweets_set.keys():
                        tweets.append(tweets_set[w])
                else:
                    continue
            except:
                requestUrl = "None"
                continue
        else:
            continue
    if len(tweets) != 0:
        tweets_json=json.loads(json.dumps(tweets, ensure_ascii=False))
        user_tweets=[]
        for i in tweets_json:
            tweet = {}
            tweet["id"] = i["id"]
            tweet["full_text"] = i["full_text"]
            tweet["created_at"] = i["created_at"]
            user_tweets.append(tweet)

        return user_tweets
    else:
        return None

多进程

这里用了队列来载入需要爬取的推特推文id,通过这个队列来给不同的进程分配任务,每一个进程都从队列获取推文id,然后根据这个推文id来爬取相应的信息,在这个推文id的信息爬取完后,会把这个推文id写入finished.txt中,这样在整个爬取过程中如果程序中断,从中断点能恢复任务,继续爬虫。

import multiprocessing
def multi_scrap_tree_func( queue, dataset_path,i):
    browser = scrap2.init_browser(i)
    while not queue.empty():
    #从队列中获取推特id
        file = queue.get()
        file_path = os.path.join(dataset_path,file)
        get_tree_user(browser,file_path)
        logging.debug(file+" is scrapped")
        with open("./data/twitter15/finished.txt",mode="a", encoding="utf-8") as f:
            f.write(file+"\n")
        print("process{}:{} / {} ,{} is finished".format(i,len(twi16_dir_ls)-queue.qsize(),len(twi16_dir_ls),file))


if __name__ == '__main__':

    lock = multiprocessing.Lock()
    queue = multiprocessing.Queue()
    continue_file = ""
    #读取已完成爬取的推文id
    with open("./data/twitter15/finished.txt",mode="r",encoding="utf-8") as f:
        finished_file_list = f.readlines()
    for i in range(len(twi16_dir_ls)):
        is_finished = False
        #如果一个推文id已经完成爬取,就不加入队列中
        for j in finished_file_list:
            if j[:-1]==twi16_dir_ls[i]:
                is_finished=True
        if not is_finished:
            queue.put(twi16_dir_ls[i])
    print(queue.qsize())
    process_list = []

    for i in range(12):#创建12个进程
        process = multiprocessing.Process(target=multi_scrap_tree_func,args=(queue,twi16_dir,i))
        process.start()
        process_list.append(process)
    for p in process_list:
        p.join()

结语

在有现成API的情况下,用selenium来爬数据确实不够优雅,开12个chrome的性能需求太大了。但是因为我爬的数据量大,以及推特的登陆和请求次数限制,用request和httpx来爬数据在时间上也不会特别快。不过以后还是可以学学用requests和httpx爬数据文章来源地址https://www.toymoban.com/news/detail-820623.html

到了这里,关于【爬虫】用selenium登陆推特并爬取用户历史推文的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • selenium处理登陆爬虫(维持登陆状态请求页面)

    selenium在处理需要登陆的时候,需要修改浏览器请求头参数cookie或token,在请求需要登陆的页面时,添加参数,跳过登陆,直接获取登陆后的内容。 处理思路 浏览器先登陆,请求同一个域名下的网页,抓包,提取浏览器内的cookie字符串,如: 标红的字符串直接复制,并解析为

    2024年02月12日
    浏览(37)
  • selenium保留网页登陆信息(保留用户数据)

    打开谷歌浏览器访问 chrome://version/  找到这个路径,把结尾的default去掉  输入以上代码再打开浏览器就是登录的状态了 注意: 运行前要把谷歌浏览器的进程清理完,把所有的网页都关掉 如果还不行就cmd输入tasklist | findstr chrome查看一下,如果还有进程就kill一下所有的chrome

    2024年02月11日
    浏览(40)
  • 爬虫——python爬取京东商品用户评价

    以小米手环7为例,分别爬取小米手环7用户评价中的好评、中评、差评 使用工具:PyCharm Community 需要python库:requests 安装方法:File--Settings--Project --Python Interpreter 代码如下: 好评: 中评: 差评: 其中重要参数来源: 打开开发者工具,快捷键F12键,或鼠标右键--检查--网络

    2024年02月11日
    浏览(47)
  • selenium爬虫框架爬取某壁纸网站

    基础知识 环境配置 开始爬虫 简单分析目标网站 写函数 获取浏览器对象: 下载每一张图片: 获取每一页的源代码: 运行print_result_every_page python基础语法 面向对象基础 html基础 xpath基础 selenium框架的基本使用 request库 lxml库      3.安装浏览器xpath插件         打开谷歌浏览

    2024年02月05日
    浏览(44)
  • 【爬虫】5.5 Selenium 爬取Ajax网页数据

    目录   AJAX 简介 任务目标 创建Ajax网站 创建服务器程序 编写爬虫程序         AJAX(Asynchronous JavaScript And XML,异步 JavaScript 及 XML) Asynchronous 一种创建 交互式 、 快速动态 网页应用的网页开发技术 通过在后台与服务器进行少量数据交换,无需重新加载整个网页的情况下

    2024年02月10日
    浏览(45)
  • Python爬虫|使用Selenium轻松爬取网页数据

    1. 什么是selenium? Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作浏览器一样。支持的浏览器包括IE,Firefox,Safari,Chrome等。 Selenium可以驱动浏览器自动执行自定义好的逻辑代码,也就是可以通过代码完全模拟成人类使用

    2024年02月04日
    浏览(58)
  • 爬虫项目实战2.1 Selenium爬取Boss招聘信息

    完成: 1.爬取信息 2.基于爬取结果筛选符合条件的信息    岗位名称、薪资、岗位要求、地区、公司名称、公司规模、细节链接 3.筛选base杭州的岗位保存到csv文件中 But容易出现网络不稳定造成的无法定位元素所在位置的情况,小范围爬取可以 4.基于csv分析后续

    2024年02月05日
    浏览(48)
  • python爬虫实战 scrapy+selenium爬取动态网页

    最近学习了scrapy爬虫框架,想要找个目标练练手。由于现在很多网页都是动态的,因此还需要配合selenium爬取。本文旨在记录这次学习经历,如有疑问或不当之处,可以在评论区指出,一起学习。 对scrapy不了解的同学可以阅读这篇文章 爬虫框架 Scrapy 详解,对scrapy框架介绍的

    2024年02月07日
    浏览(83)
  • 【爬虫】7.1. JavaScript动态渲染界面爬取-Selenium

    引言:在学习这一章之前,若之前对于Ajax数据的分析和爬取有过了解的会知道,Ajax是JavaScript动态渲染界面的一种情形,通过直接分析Ajax,使我们仍然可以借助requests或urllib实现数据爬取。不过JavaScript动态渲染的界面不止Ajax一种,而且在实际中Ajax接口中会含有很多加密参数

    2024年02月09日
    浏览(50)
  • selenium保持用户登陆的方法(获取cookie和添加cookie)

    目录 获得cookie 实现登陆 首先在用户登陆界面手动获取用selenium点击等操作获得cookie,并保存至txt 在新链接添加cookie实现用户保持登陆

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包