python - pool.map 列表索引超出范围 python

标签 python windows python-2.7 multiprocessing pool

大约有 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 use pool.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/

相关文章:

python - 在python中绘制带有图例的垂直线

Python ECDSA,用曲线 secp224k1 用私钥签名

python - 多处理全局变量内存复制

python - 如何解析包含 "st"、 "nd"、 "rd"或 "th"的日期?

python-2.7 - Mincemeat:提供额外的参数来映射和减少带有闭包的函数

python - 使用 eval 优化 Python 读取大文件

c++ - 您可以将 LPTSTR 转换为 BSTR 吗?

python - 在 virtualenv 中设置环境变量(Python、Windows)

java - 重命名文件的程序出现问题

python - 是否可以在Python中运行实例变量