2016-10-03 3 views
0

Использовал красивый суп, чтобы перебирать страницы, но по какой-то причине я не могу заставить цикл продвигаться за пределы первой страницы. кажется, что это должно быть легко, потому что это текстовая строка, но, похоже, она возвращается назад, может быть, это моя структура, а не моя текстовая строка?петля застряла на первой странице

Вот что у меня есть:

import csv 
import urllib2 
from bs4 import BeautifulSoup 

f = open('nhlstats.csv', "w") 


groups=['points', 'shooting', 'goaltending', 'defensive', 'timeonice', 'faceoffs', 'minor-penalties', 'major-penalties'] 

year = ["2016", "2015","2014","2013","2012"] 

for yr in year: 
    for gr in groups: 
     url = "http://www.espn.com/nhl/statistics/player/_/stat/points/year/"+str(yr) 
    #www.espn.com/nhl/statistics/player/_/stat/points/year/2014/ 
    page = urllib2.urlopen(url) 
    soup=BeautifulSoup(page, "html.parser") 
    pagecount = soup.findAll(attrs= {"class":"page-numbers"})[0].string 
    pageliteral = int(pagecount[5:]) 
    for i in range(0,pageliteral): 
     number = int(((i*40) + 1)) 
     URL = "http://www.espn.com/nhl/statistics/player/_/stat/points/sort/points/year/"+str(yr) + "/count/"+str(number) 
     page = urllib2.urlopen(url) 
     soup=BeautifulSoup(page, "html.parser") 
     for tr in soup.select("#my-players-table tr[class*=player]"): 
      row =[] 
      for ob in range(1,15): 
       player_info = tr('td')[ob].get_text(strip=True) 
       row.append(player_info) 
      f.write(str(yr) +","+",".join(row) + "\n") 

f.close() 

это получает те же первые 40 записей снова и снова.

Я попытался с помощью this solution как если и нашли, что делает

prevLink = soup.select('a[rel="nofollow"]')[0] 
newurl = "http:" + prevLink.get('href') 

сделал работу лучше, но я не уверен, как сделать петлю таким образом, что он продвигается? возможно, просто устал, но моя петля все еще просто переходит к следующему набору записей и застревает на , что один. Пожалуйста, помогите мне исправить мою петлю

UPDATE

мое форматирование было потеряно в копии пасты, мой фактический код выглядит следующим образом:

import csv 
import urllib2 
from bs4 import BeautifulSoup 

f = open('nhlstats.csv', "w") 


groups=['points', 'shooting', 'goaltending', 'defensive', 'timeonice', 'faceoffs', 'minor-penalties', 'major-penalties'] 

year = ["2016", "2015","2014","2013","2012"] 


for yr in year: 
    for gr in groups: 
     url = "http://www.espn.com/nhl/statistics/player/_/stat/points/year/"+str(yr) 
    #www.espn.com/nhl/statistics/player/_/stat/points/year/2014/ 
     page = urllib2.urlopen(url) 
     soup=BeautifulSoup(page, "html.parser") 
     pagecount = soup.findAll(attrs= {"class":"page-numbers"})[0].string 
     pageliteral = int(pagecount[5:]) 
     for i in range(0,pageliteral): 
      number = int(((i*40) + 1)) 
      URL = "http://www.espn.com/nhl/statistics/player/_/stat/points/sort/points/year/"+str(yr) + "/count/"+str(number) 
      page = urllib2.urlopen(url) 
      soup=BeautifulSoup(page, "html.parser") 
      for tr in soup.select("#my-players-table tr[class*=player]"): 
       row =[] 
       for ob in range(1,15): 
        player_info = tr('td')[ob].get_text(strip=True) 
        row.append(player_info) 
       f.write(str(yr) +","+",".join(row) + "\n") 

f.close() 
+0

Я не могу видеть, как вы получите первую страницу на всех. Так выглядит ваш код? –

+0

Ошибка отступа, которую люди комментируют, на самом деле просто потеряла форматирование из моей копии вставить в stackoverflow ... обновление с фактическим форматированием. – ike

ответ

1

Ваш код отступы в основном по вине. Также было бы разумно использовать CSV-библиотеку, которую вы импортировали, это автоматически обернет имена игроков в кавычки, чтобы избежать каких-либо запятых внутри от разрушения структуры csv.

Это работает, ища ссылку на следующую страницу и извлечение начального счета. Затем это используется для создания следующей страницы. Если следующая страница не найдена, она перемещается в группу следующего года. Обратите внимание, что счетчик не является числом страниц, а считается стартовым.

import csv 
import urllib2 
from bs4 import BeautifulSoup 


groups= ['points', 'shooting', 'goaltending', 'defensive', 'timeonice', 'faceoffs', 'minor-penalties', 'major-penalties'] 
year = ["2016", "2015", "2014", "2013", "2012"] 

with open('nhlstats.csv', "wb") as f_output: 
    csv_output = csv.writer(f_output) 

    for yr in year: 
     for gr in groups: 
      start_count = 1 
      while True: 
       #print "{}, {}, {}".format(yr, gr, start_count)  # show progress 

       url = "http://www.espn.com/nhl/statistics/player/_/stat/points/sort/points/year/{}/count/{}".format(yr, start_count) 
       page = urllib2.urlopen(url) 
       soup = BeautifulSoup(page, "html.parser") 

       for tr in soup.select("#my-players-table tr[class*=player]"): 
        row = [yr] 
        for ob in range(1, 15): 
         player_info = tr('td')[ob].get_text(strip=True) 
         row.append(player_info) 

        csv_output.writerow(row) 

       try: 
        start_count = int(soup.find(attrs= {"class":"page-numbers"}).find_next('a')['href'].rsplit('/', 1)[1]) 
       except: 
        break 

Использование with также автоматически закрыть файл в конце.

Это даст вам файл CSV, начиная следующим образом:

2016,"Patrick Kane, RW",CHI,82,46,60,106,17,30,1.29,287,16.0,9,17,20 
2016,"Jamie Benn, LW",DAL,82,41,48,89,7,64,1.09,247,16.6,5,17,13 
2016,"Sidney Crosby, C",PIT,80,36,49,85,19,42,1.06,248,14.5,9,10,14 
2016,"Joe Thornton, C",SJ,82,19,63,82,25,54,1.00,121,15.7,6,8,21 
+0

Это сработало отлично! Я сделал несколько модов: 1) Я добавил в переменную для столбца сортировки, так как точки не были согласованы между столбцами. 2) Я закончил делать raw_input для каждой переменной, так как иначе он будет перебирать каждый элемент для каждой пары ключей. Это также имело побочное преимущество не бросать вратарей. незначительные замечания: 1) Вы можете объяснить, как работает перескакивание страницы? они были прекрасны, любопытно, как это работает, чтобы я мог учиться. 2) Я действительно хотел, чтобы имена были не отсортированы, поэтому они разделились бы на запятую и создавали столбец для позиции после открытия csv.есть способ отключить это? – ike

+1

На сайте отображается «1 из 20», но требуемый URL-адрес - это счет. Таким образом, IF 50 записей были на первой странице, вторая страница начиналась с URL-адреса, имеющего 51. Код ищет это в URL-адресе после класса 'page-numbers'. Теоретически вместо этого используется весь код URL. –

+1

Если вы не укажете записи csv, будет переменное количество столбцов, поэтому данные никогда не будут правильно выровнены, если они открыты в Excel, например. Вы можете добавить 'quoting = csv.QUOTE_NONE, escapechar = '', quotechar = ''' параметрам записи, чтобы отключить цитирование. Это сделает чтение файла очень сложным. 'Csv.reader()' автоматически анализирует и удаляет цитирование, если вы его прочитаете. –

0

Вы меняете URL-адрес много раз, прежде чем вы открываете это первый раз из-за ошибки вдавливания. Попробуйте это:

for gr in groups: url = "...some_url..." page = urllib2.urlopen(url) ...everything else should be indented....

+0

спасибо за быстрый ответ, к сожалению, как отмечено, это была ошибка копирования/вставки. фактический код повторно размещен – ike

Смежные вопросы