2017-02-11 9 views
0

есть около 70% вероятность показывает ошибку:pool.map индекс списка из диапазона питона

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% шанс показать, что message.any один есть идея, как улучшить?

#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: Тело не может содержать «пул ma p». изменил его как res = pool.map4 (feng, urls) Я пытаюсь получить некоторую подстроку с этого сайта с многопроцессорной обработкой.

+1

Мы не можем вам помочь, если вы не предоставите нам код, а B) объясните, что он пытается сделать ... – Toastrackenigma

+0

Я попробовал, система сказала, что я написал слишком много кода, я постараюсь загрузите рис. –

+0

код загружен .. –

ответ

0

Действительно, multiprocessing делает его немного трудно отладить как вы не видите, где произошла ошибка index out of bound (сообщение об ошибке делает вид, как будто это произошло внутри в multiprocessing модуле).

В некоторых случаях эта линия:

content=str(soupout[1]) 

поднимает index out of bound, потому что 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 является более стабильным, особенно если сайт немного изменяет их разметки (например, пробелы и т.д.)

Update:

why is soupout is an empty list? When I didn't use pool.map never I have this error message shown

Возможно, это связано с тем, что вы слишком быстро забиваете веб-сервер. В комментарии вы упомянули, что иногда получаете 504 в response.status_code. 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, что является обратным прокси-сервером. Теперь обратный прокси обрабатывает все запросы, которые вы отправили ему на веб-сервер, и если теперь вы запускаете слишком много процессов, то бедный веб-сервер не может справиться с потоком. Kangle has a default timeout of 60s, так как он не получит ответ с веб-сервера в течение 60-х, он показывает сообщение об ошибке, которое вы опубликовали.

Как вы это исправите?

  • можно ограничить число процессов: pool=multiprocessing.Pool(2), вы должны играть с хорошим количеством процессов
  • в верхней части feng(url) можно добавить time.sleep(5) поэтому каждый процесс ожидает 5 секунд между каждым запрос. Также здесь вам нужно будет поиграть со временем сна.
+0

большое спасибо, я попробую позже –

+0

это сработало, но я до сих пор не знаю, почему soupout - это пустой список, и когда я не использовал функцию 'pol map func', никогда не имел этого появится сообщение об ошибке –

+0

, возможно, вы слишком быстро взламываете веб-сервер, поэтому он возвращает либо код ответа «50x», либо страницу с «200» и отображающую ошибку. Попробуйте 'print (response.status_code)' внутри 'if len (soupout) == 0' block – hansaplast