【发布时间】: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