【问题标题】:Improving the speed of a web scraper提高网络抓取工具的速度
【发布时间】:2017-03-10 15:03:54
【问题描述】:

我创建了一个网络爬虫来提取在数字图书馆 (sample document) 中发表的研究论文的信息。

基本上,我会提取每篇论文的标题、摘要和参考文献列表,并将它们存储在文本文件中。对所有参考论文也重复此过程。

  • 我使用队列来存储文档 ID。
  • 我需要从至少 5000 篇论文中提取此类信息,但是程序太慢,需要大约 3 个小时才能通过 250-300 篇论文。

有哪些可能的方法来提高这个爬虫的速度?

代码如下:

# _*_ coding:utf-8 _*_
import urllib2
import json
import Queue

crawled = []

fo = open("paper.txt", "w")

class Paper(object):
    def __init__(self, paper_id):
        self.paper_id = paper_id
        self.title, self.abstract = self.fetch_data()

    def fetch_data(self):
        base_url = "http://ieeexplore.ieee.org/rest/document/{0}/{1}"
        data_url = base_url.format(self.paper_id, "abstract")
        response = urllib2.urlopen(data_url)
        html = response.readlines()
        data = json.loads("\n".join(html))
        title = data["title"]
        abstract = data["abstract"]
        return title, abstract

    def fetch_ieee_references(self):
        base_url = "http://ieeexplore.ieee.org/rest/document/{0}/{1}"
        data_url = base_url.format(self.paper_id, "references")
        response = urllib2.urlopen(data_url)
        html = response.readlines()
        data = json.loads("\n".join(html))
        references = []
        try:
            for ref in data["references"]:
                try:
                    ref_link = ref["links"]["documentLink"]
                    ref_paper_id = ref_link.split("/")[-1]
                    references.append(Paper(ref_paper_id))
                except:
                    pass
       except:
           pass
       return references
    def extract_paper(self):
        try:
            print "Paper ID"
            print self.paper_id
            fname = str(self.paper_id)
            fname = fname + ".txt"
            fcon = open(fname,"w")
            print
            print "Title"
            print self.title
            print >>fcon, self.title
            print "Abstract"
            print self.abstract
            print >>fcon, self.abstract
            print "References"
            for ref in self.fetch_ieee_references():
                print ref.paper_id, ref.title
                print >>fo, self.paper_id, ref.paper_id
        except:
            pass


def new_func():
    n_id = 6639344
    q = Queue.Queue()
    q.put_nowait(n_id)
    crawled.append(n_id)
    while not q.empty():
        p_id = q.get_nowait()
        paper = Paper(p_id)
        paper.extract_paper()
        for ref in paper.fetch_ieee_references():
            if ref.paper_id not in crawled:
                crawled.append(ref.paper_id)
                q.put_nowait(ref.paper_id)

new_func()                

【问题讨论】:

  • 几乎所有时间都取决于 HTTP 请求/响应时间和服务器的可用性。而且它并不总是在我们的控制之下。
  • 对于工作代码的代码改进和优化:codereview.stackexchange.com
  • 沿着这条评论,因为HTTP请求是你的瓶颈,所以专注于让它一直运行。您不应该在 HTTP 调用之间分析同一线程上的文本。尝试让一个线程运行所有 ID 并将 HTTP 调用的结果排队,另一个线程构建纸对象,从这些结果中输入数据,而不是从 init 执行 HTTP

标签: python web-scraping web-crawler


【解决方案1】:

正如其他用户已经提到的,它主要取决于 HTTP 请求的速度,因此您依赖于站点的服务器。因此,为了加快速度,您可以在多个进程之间划分论文。 另外我不明白你为什么要阅读 html 然后使用 json.loads 你可以在响应上使用 json.load ,这会加快速度。

【讨论】:

    猜你喜欢
    • 2019-04-23
    • 1970-01-01
    • 2022-06-30
    • 2023-01-25
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多