首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >利用碎片/selenium加速网页解析

利用碎片/selenium加速网页解析
EN

Stack Overflow用户
提问于 2020-07-20 09:32:52
回答 1查看 164关注 0票数 1

我正在努力实现如下的目标。

  1. 使用碎片访问URL
  2. 使用多进程( multiprocessing.Process )将浏览器实例传递给所有方法
  3. 所有方法都在线程中执行,从而缩短了整个时间。

示例代码如下所示。

代码语言:javascript
复制
from splinter import Browser
from multiprocessing import Process, Queue, current_process, freeze_support

#
# Function run by worker processes
#

def worker(input, output):
    for func, args in iter(input.get, 'STOP'):
        result = calculate(func, args)
        output.put(result)

#
# Function used to calculate result
#

def calculate(func, args):
    print(args)
    result = func(*args)
    return '%s says that %s%s = %s' % \
        (current_process().name, func.__name__, args, result)


def get_meta_tag_title(browser):
    return browser.find_by_xpath('//title')[0]['text']

def get_meta_tag_description(browser):
    return browser.find_by_xpath('//description')[0]['text']

#
#
#

def test():
    browser = Browser(headless=True)
    browser.visit('https://example.com')
    NUMBER_OF_PROCESSES = 2
    TASKS1 = [(get_meta_tag_title, (browser)), (get_meta_tag_description, (browser))]

    # Create queues
    task_queue = Queue()
    done_queue = Queue()


    # Submit tasks
    for task in TASKS1:
        task_queue.put(task)

    # Start worker processes
    for i in range(NUMBER_OF_PROCESSES):
        Process(target=worker, args=(task_queue, done_queue)).start()

    # Get and print results
    print('Unordered results:')
    for i in range(len(TASKS1)):
        print('\t', done_queue.get())

    browser.quit()


if __name__ == '__main__':
    freeze_support()
    test()

我的问题是-

  1. 使用浏览器实例获取所有元素信息/值是否是正确的方法?
  2. TypeError: cannot serialize '_io.BufferedWriter' object中将浏览器实例添加到队列结果中,我应该使用池吗?
EN

回答 1

Stack Overflow用户

发布于 2020-07-23 16:43:31

Splinter基于selenium的WebDriver,即非螺纹安全,因此您可能不应该在生产中使用它在单独的线程中。实际上,它可能会起作用,因为您正在执行的操作是只读的。另一个不使用线程的可能原因是,您试图并行化的操作是cpu密集型的,而且在大多数情况下,python线程不会因为GIL而提高性能。

另一方面,多处理确实可以帮助您并行处理cpu密集型工作.但是将浏览器对象传递给每个工作进程(就像您所做的那样)将无法工作,因为浏览器保存打开的文件、套接字,并且有自己的有状态驱动程序实例。这些不能被琐碎的复制和传递到另一个进程。相反,您可以做的是在每个工作人员中创建一个浏览器对象,导航到页面,然后在页面上执行任务。

编辑

要进一步缩短执行时间,可以尝试:

  1. 使用find_by_xpath以外的定位器方法,在遍历整个DOM时,它本身就很慢。
  2. 使用requests库获取html内容,使用lxml解析它,而不是使用selenium,因为webdriver可能会造成一些严重的开销。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62992526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档