- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想在我的网络爬虫中添加多线程,但我可以看到蜘蛛计划要抓取的链接的方式可能与多线程不兼容。爬虫只会在少数新闻网站上处于事件状态,但我更愿意在同一域上打开多个线程,而不是为每个域启动一个新线程。我的网页爬取代码是通过以下函数操作的:
def crawl_links():
links_to_crawl.append(domain[0])
while len(links_to_crawl) > 0:
link = links_to_crawl[0]
if link in crawled_links or link in ignored_links:
del links_to_crawl[0]
else:
print '\n', link
try:
html = get_html(link)
GetLinks(html)
SaveFile(html)
crawled_links.append(links_to_crawl.pop(0))
except (ValueError, urllib2.URLError, Timeout.Timeout, httplib.IncompleteRead):
ignored_links.append(link_to_crawl.pop(0))
print 'Spider finished!'
print 'Ignored links:\n', ignored_links
print 'Crawled links:\n', crawled_links
print 'Relative links\n', relative_links
如果我对线程如何工作的理解是正确的,如果我只是在此过程中打开多个线程,它们将全部抓取相同的链接(可能多次)或者它们会有点冲突。无需详细说明,您建议如何重组调度以使其与同时运行的多个线程兼容?
我已经考虑过这个问题,我能想出的唯一解决方法是让 GetLinks()
类将链接附加到多个列表,每个线程有一个单独的列表……但是这个这似乎是一个相当笨拙的解决方法。
最佳答案
这是我用来在 Python 中运行多线程应用程序的通用方案。
该方案采用输入参数表,并为每一行并行执行一个线程。
每个线程占用一行,并为行中的每个项目顺序执行一个线程。
每个项目都包含固定数量的参数,这些参数将传递给执行的线程。
输入示例:
table = \
[
[[12,32,34],[11,20,14],[33,67,56],[10,20,45]],
[[21,21,67],[44,34,74],[23,12,54],[31,23,13]],
[[31,67,56],[34,22,67],[87,74,52],[87,74,52]],
]
在这个例子中,我们将有 3 个线程并行运行,每个线程依次执行 4 个线程。
为了保持线程平衡,建议每行中的项目数相同。
线程方案:
import threading
import MyClass # This is for you to implement
def RunThreads(outFileName,errFileName):
# Create a shared object for saving the output of different threads
outFile = CriticalSection(outFileName)
# Create a shared object for saving the errors of different threads
errFile = CriticalSection(errFileName)
# Run in parallel one thread for each row in the input table
RunParallelThreads(outFile,errFile)
def RunParallelThreads(outFile,errFile):
# Create all the parallel threads
threads = [threading.Thread(target=RunSequentialThreads,args=(outFile,errFile,row)) for row in table]
# Start all the parallel threads
for thread in threads: thread.start()
# Wait for all the parallel threads to complete
for thread in threads: thread.join()
def RunSequentialThreads(outFile,errFile,row):
myObject = MyClass()
for item in row:
# Create a thread with the arguments given in the current item
thread = threading.Thread(target=myObject.Run,args=(outFile,errFile,item[0],item[1],item[2]))
# Start the thread
thread.start()
# Wait for the thread to complete, but only up to 600 seconds
thread.join(600)
# Terminate the thread if it hasn't completed up to this point
if thread.isAlive():
thread._Thread__stop()
errFile.write('Timeout on arguments: '+item[0]+' '+item[1]+' '+item[2]+'\n')
下面的类实现了一个可以在并行运行的不同线程之间安全共享的对象。它提供了一个名为 write
的单一接口(interface)方法,它允许任何线程以安全的方式更新共享对象(即,操作系统不会在此过程中切换到另一个线程)。
import codecs
class CriticalSection:
def __init__(self,fileName):
self.mutex = threading.Lock()
self.fileDesc = codecs.open(fileName,mode='w',encoding='utf-8')
def __del__(self):
del self.mutex
self.fileDesc.close()
def write(self,data):
self.mutex.acquire()
self.fileDesc.write(data)
self.mutex.release()
上述方案应该允许您控制应用程序中的“并行性”级别和“顺序性”级别。
例如,您可以对所有项目使用一行,并让您的应用程序以完全顺序的方式运行。
相比之下,您可以将每个项目放在单独的行中,并让您的应用程序以完全并行的方式运行。
当然,您可以选择以上任意组合...
注意:
在 MyClass
中,您需要实现方法 Run
,它将获取 outFile
和 errFile
对象,以及您为每个线程定义的参数。
关于python - 网络爬虫的线程建议 - 使用单个列表进行调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21174416/
我在一个网站上工作。 我需要了解我的网站是否获得了来自 Google 或任何其他搜索引擎的抓取工具/机器人的访问 在我的应用程序中,我正在拦截 http 请求。并且需要查明爬虫/机器人是否正在发出 h
我与北京理工大学python爬虫的邂逅 在人生的旅途中,我们时常有机会邂逅一些惊艳的事物,它们仿佛一束亮光照亮了前行的道路。而我,一个平凡的人类,也不例外。回想起那个让我心动的时刻,我想起了与北京理工
从“爬虫”谈起 在这个信息爆炸的时代,互联网上的数据宛如茫茫星海,琳琅满目。但是,我们能否想象到这些数据背后隐藏着多少珍贵的信息呢?有人说,要想获得这些数据,我们需要借助一种神奇的力量——爬虫。 什么
探索未知的领域 曾几何时,我陷入了对互联网世界的好奇之中。作为一个普通的人类,我对于计算机技术的了解可谓是一窍不通。然而,好奇心驱使着我踏上了学习的征途。 奇妙的爬虫 在探索计算机领域的过程中,我翻阅
教室的奇妙之旅 在一个晴朗的早晨,我来到了一所神奇且富有魅力的教室。这里充满了未知的冒险和无限的学习可能。嘿,你没听错,就是那个零基础Python视频教程课程的教室!让我带你一起踏上这趟令人期待的爬虫
零基础学python3 爬虫 嗨,各位小伙伴们!今天要和大家分享一段有关学习Python3爬虫的故事。无论是技术小白还是编程高手,都可以从中获益良多。 1. 邂逅神奇的爬虫世界 就像是迷失在未知之地的
我正在开发一个 Python(3) 程序,在该程序中,我必须使用输入作为表示各种操作的多次迭代列表来返回目录迭代的移动次数,例如: ../ 表示移动到当前文件夹的父文件夹。 ./ 保留在同一文件夹中
我和Python:一段关于爬虫和第三方库的故事 曾经有一个人,他和一门编程语言结下了不解之缘。这门语言就是Python,一个灵活而强大的工具,让他的世界变得多姿多彩。 遇见爬虫:探索未知的世界 某天,
偷心技艺:大众点评TOP10 爬虫 Python 故事发生在一个被互联网包围的城市,充满了各种各样的餐馆、咖啡厅和美食街巷。每天都有无数的食客们纠结于选择哪家餐厅才能获得满足和享受。就在这个时候,我偶
登山寻宝:为什么Python爬虫部分网页源码 人生就像登山寻宝的旅程,充满了未知和挑战。而对于爱好编程的我来说,写一个Python爬虫,探索网络世界也是一种刺激的冒险。今天,我想和大家分享一下为什么要
插班生的悲喜交加 记得那个夏天,我踏入了编程的殿堂,成为了一名程序员。对于一个毫无基础的人来说,这是一次勇敢而激动的尝试。然而,更令我兴奋的是,在我的码农之旅中,我发现了一种神奇的力量——Python
一、 意外的宝藏 当我踏进了编程的大门,发现了那个绚丽多彩的世界时,我仿佛捡到了一个意外的宝藏。在编码的世界里,我像是一个魔术师,用着神奇的符号与逻辑来创造奇迹。然而,随着时间的推移,我渐渐找到了一种
“呜呜呜~” 夏日的阳光穿过微风,洒在我身上,仿佛一片温暖而宁静的海洋。我望着眼前充满希望与挑战的屏幕,满脸的期待和困惑。作为一个刚刚入门的编程初学者,我竭尽全力探索着那座神秘的编程世界,好像是航行在
我的编程之旅 嗨,大家好!我是一个普通的人类,对于编程世界充满着无限的好奇和热情。今天,我想向大家讲述一段关于我的编程经历,特别是在爬虫领域的探索之旅。 1. 踏上未知的征途 就像一只踏上大海的小船,
揭秘神奇的爬虫世界:探寻京东销量数据库 从古至今,人类一直渴望了解世界的各个角落。而对于互联网这个充满未知和神秘的领域来说,我们更是怀着好奇和充满冒险精神的心态去探索。今天,我将带领大家踏上一段激动人
啊!你好呀!很高兴能遇到你,让我向你讲一个关于python爬虫爬取关键词排名的故事。 章节一:奇妙的网络世界 网络就像一片浩瀚的海洋,里面有无数宝藏等待着我们发掘。而当我们学会了使用python这把钥
一次意外的奇遇 在我们生活的世界中,技术如今已经无处不在,无论是大型软件开发还是个人应用,都离不开它的支持。而其中最为神奇的领域之一,就是爬虫技术。想象一下,你有可能仅凭几行代码,就能够在电脑屏幕上将
奇遇之旅 在这个大千世界中,我有幸踏上了一次令人兴奋的冒险之旅。故事的开始,是一个寂静而神秘的夜晚。 迷宫的入口 深夜的城市,街道上弥漫着微弱的灯光,仿佛点缀着无数的星星。我沿着曲径通幽的小巷走着,脚
python 爬虫 自动上传下载 从前有一个热爱编程的小伙子,他喜欢利用自己的技术解决各种实际问题。有一天,他面对一个任务:需要在网络上批量上传和下载文件。这可不是一件轻松的工作,但对于这位小伙子来说
一场奇妙的探险之旅:Python编程语言中的爬虫第三方库 故事从一个寻宝者开始。他身穿一件斑驳的皮衣,手持一柄锈迹斑斑的剑,如同一个当代版的荒野游侠。这位勇士的目标是探索Python编程语言中的神秘领
我是一名优秀的程序员,十分优秀!