我将继续阅读一本名为Python Web Scraping-第二版的Packt书,其中的参考代码来自https://github.com/kjam/wswp/tree/master/code/chp4 而且我的帖子标题中总是出现错误。
代码确实可以在macOS上运行,并且据我了解,问题可能出在Windows和Linux之间的fork vs spawn差异上。我是多处理的新手,无法弄清楚需要更改哪些内容和位置才能使其在Windows上正确运行。任何帮助表示赞赏。
基于在SO上的一些挖掘,我尝试了multiprocessing.set_start_method(“ spawn”)无济于事。
julia> a = [1,2,3]
3-element Array{Int64,1}:
1
2
3
julia> b = [1,2,3]
3-element Array{Int64,1}:
1
2
3
julia> a .* b
3-element Array{Int64,1}:
1
4
9
错误:
import multiprocessing
import time
def threaded_crawler_rq(start_url, link_regex, user_agent='wswp', proxies=None,
delay=3, max_depth=4, num_retries=2, cache={}, max_threads=10, scraper_callback=None):
"""
Comments
"""
def mp_threaded_crawler(*args, **kwargs):
""" create a multiprocessing threaded crawler """
processes = []
num_procs = kwargs.pop('num_procs')
if not num_procs:
num_procs = multiprocessing.cpu_count()
for _ in range(num_procs):
proc = multiprocessing.Process(target=threaded_crawler_rq,
args=args, kwargs=kwargs)
proc.start()
processes.append(proc)
# wait for processes to complete
for proc in processes:
proc.join()
if __name__ == '__main__':
from chp4.alexa_callback import AlexaCallback
from chp3.rediscache import RedisCache
import argparse
parser = argparse.ArgumentParser(description='Multiprocessing threaded link crawler')
parser.add_argument('max_threads', type=int, help='maximum number of threads',
nargs='?', default=5)
parser.add_argument('num_procs', type=int, help='number of processes',
nargs='?', default=None)
parser.add_argument('url_pattern', type=str, help='regex pattern for url matching',
nargs='?', default='$^')
par_args = parser.parse_args()
AC = AlexaCallback()
AC()
start_time = time.time()
mp_threaded_crawler(AC.urls, par_args.url_pattern, cache=RedisCache(),
num_procs=par_args.num_procs, max_threads=par_args.max_threads)
print('Total time: %ss' % (time.time() - start_time))
答案 0 :(得分:0)
至少在Windows中,您提供给将在工作进程中运行的功能的参数通过引擎盖下的IPC通道传递给该进程。
因此,您无法将args
和kwargs
中的不可拾取对象传递给multiprocessing.Process()
。
(venv) C:\Users\Sasha\Documents>pip install ipdb
<...>
(venv) C:\Users\Sasha\Documents>ipdb3 t.py
> c:\users\sasha\documents\t.py(1)<module>()
----> 1 import multiprocessing
2 import time
3
ipdb> b 23
Breakpoint 1 at c:\users\sasha\documents\t.py:23
ipdb> c
> c:\users\sasha\documents\t.py(23)mp_threaded_crawler()
22 args=args, kwargs=kwargs)
1--> 23 proc.start()
24 processes.append(proc)
ipdb> p args
(['http://google.com', 'http://youtube.com', 'http://facebook.com', 'http://baidu.com', <...>
ipdb> p kwargs
{'cache': <chp3.rediscache.RedisCache object at 0x000000000560F780>, 'max_threads': 5}
ipdb> import pickle
ipdb> pickle.dumps(kwargs)
*** TypeError: can't pickle _thread.lock objects
对象不会无缘无故地被拾取。通常,这意味着它们所代表的任何内容(例如同步化原语或网络连接)本质上都是过程本地的,因此尝试将其传递给另一个进程毫无意义。