返回介绍

8.2 串行爬虫

发布于 2024-01-25 21:44:08 字数 1791 浏览 0 评论 0 收藏 0

对于在我们实验中的并发控制,我们会写一个串行的Web爬虫来使用一串URL列表,抓取它们并对页面内容的总长度求和。我们会使用一个定制的HTTP服务器,采用两个参数,name和delay。delay域会告诉服务器在得到响应前暂停多久,以毫秒计时。name域只是为了日志的目的。

通过控制delay参数,我们能够模拟服务器响应我们请求的时间。在真实的世界中,这可能对应于一个慢速的Web服务器,一个繁重的数据库调用,或是任何要花长时间运行的I/O调用。对于串行的情况,这仅仅代表了我们的程序会陷入更多的I/O等待的时间,但是在之后的并发例子中,它也代表了程序能花更多的时间来做其他事情。

此外,我们选择使用requests模块来执行HTTP调用。做出这个选择是出于这个模块的简单性。我们一般为此小节使用HTTP,因为它是一个简单的I/O例子,并且能相当容易地执行HTTP请求。一般情况下,对一个HTTP库的任何调用都能被其他I/O所代替。我们串行版本的HTTP爬虫显示于例8-3中。

例8-3 串行HTTP爬虫

import requests
import string
import random

def generate_urls(base_url, num_urls):
  """
  We add random characters to the end of the URL to break any caching
  mechanisms in the requests library or the server
  """

  for i in xrange(num_urls):
    yield base_url + "".join(random.sample(string.ascii_lowercase, 10))

def run_experiment(base_url, num_iter=500):
  response_size = 0
  for url in generate_urls(base_url, num_iter):
    response = requests.get(url)
    response_size += len(response.text)
  return response_size

if __name__ == "__main__":
  import time
  delay = 100
  num_iter = 500
  base_url = "http://127.0.0.1:8080/add?name=serial&delay={}&".format(delay)

  start = time.time()
  result = run_experiment(base_url, num_iter)
  end = time.time()
  print("Result: {}, Time: {}".format(result, end - start))
 

当运行这段代码时,会看到一个有趣的度量就是去测试HTTP服务器所见到的每个请求的起始和结束时间。这告诉我们在I/O等待期间的代码效率——因为我们的任务只是去发起HTTP请求并对返回的字节数求和,我们应该能够在等待其他请求完成的期间,发起更多的HTTP请求,并处理任何响应。

从图8-2中,我们可以看到,就如所期望的那样,我们的请求没有交织。我们在一个时间做一次请求,并且在我们转移到下一次请求之前,等待前面的请求做完。事实上,串行过程的整体运行时间很有意义,知道了这个:既然每个请求花费0.1秒(因为我们的delay参数),我们正在做500次请求,那么我们就期待整体运行时间大概是50秒。

图8-2 例8-3的HTTP请求时间表

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文