大约有 70% 的机会显示错误:
res=pool.map(feng,urls)
File "c:\Python27\lib\multiprocessing\pool.py", line 251, in map
return self.map_async(func, iterable, chunksize).get()
File "c:\Python27\lib\multiprocessing\pool.py", line 567, in get
raise self._value
IndexError: list index out of range
不知道为什么,如果数据少于100,只有5%的机会显示该消息。有人知道如何改进吗?
#coding:utf-8
import multiprocessing
import requests
import bs4
import re
import string
root_url = 'http://www.haoshiwen.org'
#index_url = root_url+'/type.php?c=1'
def xianqin_url():
f = 0
h = 0
x = 0
y = 0
b = []
l=[]
for i in range(1,64):#页数
index_url=root_url+'/type.php?c=1'+'&page='+"%s" % i
response = requests.get(index_url)
soup = bs4.BeautifulSoup(response.text,"html.parser")
x = [a.attrs.get('href') for a in soup.select('div.sons a[href^=/]')]#取出每一页的div是sons的链接
c=len(x)#一共c个链接
j=0
for j in range(c):
url = root_url+x[j]
us = str(url)
print "收集到%s" % us
l.append(url) #pool = multiprocessing.Pool(8)
return l
def feng (url) :
response = requests.get(url)
response.encoding='utf-8'
#print response.text
soup = bs4.BeautifulSoup(response.text, "html.parser")
#content = soup.select('div.shileft')
qq=str(soup)
soupout = re.findall(r"原文(.+?)</div>",qq,re.S)#以“原文”开头<div>结尾的字段
#print soupout[1]
content=str(soupout[1])
b="风"
cc=content.count(b,0,len(content))
return cc
def start_process():
print 'Starting',multiprocessing.current_process().name
def feng (url) :
response = requests.get(url)
response.encoding='utf-8'
#print response.text
soup = bs4.BeautifulSoup(response.text, "html.parser")
#content = soup.select('div.shileft')
qq=str(soup)
soupout = re.findall(r"原文(.+?)</div>",qq,re.S)#以“原文”开头<div>结尾的字段
#print soupout[1]
content=str(soupout[1])
b="风"
c="花"
d="雪"
e="月"
f=content.count(b,0,len(content))
h=content.count(c,0,len(content))
x=content.count(d,0,len(content))
y=content.count(e,0,len(content))
return f,h,x,y
def find(urls):
r= [0,0,0,0]
pool=multiprocessing.Pool()
res=pool.map4(feng,urls)
for i in range(len(res)):
r=map(lambda (a,b):a+b, zip(r,res[i]))
return r
if __name__=="__main__":
print "开始收集网址"
qurls=xianqin_url()
print "收集到%s个链接" % len(qurls)
print "开始匹配先秦诗文"
find(qurls)
print '''
%s篇先秦文章中:
---------------------------
风有:%s
花有:%s
雪有:%s
月有:%s
数据来源:%s
''' % (len(qurls),find(qurls)[0],find(qurls)[1],find(qurls)[2],find(qurls)[3],root_url)
stackoverflow:主体不能包含“`pool ma p”。 将其更改为 res=pool.map4(feng,urls) 我正在尝试通过多重处理从该网站获取一些子字符串。
最佳答案
事实上,多处理
使得调试有点困难,因为您看不到索引越界
错误发生的位置(错误消息使它看起来好像它发生在多处理
模块内部)。
在某些情况下,这一行:
content=str(soupout[1])
引发索引越界
,因为 soupout 是一个空列表。如果你把它改成
if len(soupout) == 0:
return None
然后删除通过更改返回的None
res=pool.map(feng,urls)
进入
res = pool.map(feng,urls)
res = [r for r in res if r is not None]
这样就可以避免这个错误了。就是这样说的。您可能想找出 re.findall
返回空列表的根本原因。使用 beatifulsoup
选择节点肯定比使用正则表达式更好,因为通常与 bs4
匹配更稳定,特别是当网站稍微改变其标记时(例如空格)等)
更新:
why is
soupout
is an empty list? When I didn't usepool.map
never I have this error message shown
这可能是因为您对网络服务器的锤击速度太快。在评论中,您提到有时会在 response.status_code
中收到 504
。 504 表示 Gateway Time-out: The server was acting as a gateway or proxy and did not receive a timely response from the upstream server
这是因为 haoshiwen.org 似乎由 kangle 提供支持这是一个反向代理。现在,反向代理会处理您发送给后面的 Web 服务器的所有请求,如果您现在一次启动太多进程,那么可怜的 Web 服务器将无法处理洪水。康乐has a default timeout of 60s因此,一旦他在 60 秒内没有从网络服务器得到答复,他就会显示您发布的错误。
如何解决这个问题?
- 您可以限制进程数量:
pool=multiprocessing.Pool(2)
,您需要使用大量进程 - 在
feng(url)
的顶部,您可以添加time.sleep(5)
,以便每个进程在每个请求之间等待 5 秒。另外,您还需要调整 sleep 时间。
关于python - pool.map 列表索引超出范围 python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42172926/