неправильное сопоставление расписания scrapy NBA

#python #scrapy

#python #scrapy

Вопрос:

Пытаюсь запустить и запустить простой веб-скрап. Цель состоит в том, чтобы в конечном итоге выгрузить классы dt gm tm и ntv в csv. Здесь это json для ясности. Шаг за шагом.

вот паук:

 import scrapy

class QuotesSpider(scrapy.Spider):
    name = "schedule"
    start_urls = [
        'http://www.nba.com/schedules/national_tv_schedule/',
    ]

    def parse(self, response):
        for game in response.css('td'):
            yield {
                'date': game.css('td.dt::text').extract(),
                'time': game.css('td.tm::text').extract(),
            }
  

действительно просто — но выдает примерно так: (усечено для краткости)

 [
{"date": ["Sat, Oct 1", " ", "Sun, Oct 2", "Mon, Oct 3", " ", " ", " ", " ", " ", " "], "time": ["7:30 pm", "8:00 pm", "8:00 pm", "2:30 pm", "8:00 pm", "8:00 pm", "8:30 pm", "9:00 pm", "10:00 pm", "10:00 pm", "7:00 pm", "7:00 pm", "8:00 pm", "8:00 pm", "10:00 pm", "10:30 pm", "2:30 pm", "7:00 pm", "10:00 pm", "10:30 pm", "7:00 pm", "7:00 pm", "7:30 pm", "7:30 pm", "8:00 pm", "10:30 pm", "10:00 pm"]},
{"date": [], "time": []},
{"date": [], "time": []},
{"date": [], "time": []},
{"date": [], "time": []},
{"date": [], "time": []},
{"date": ["Sat, Oct 1"], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["7:30 pm"]},
{"date": [], "time": []},
{"date": [" "], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["8:00 pm"]},
{"date": [], "time": []},
{"date": ["Sun, Oct 2"], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["8:00 pm"]},
{"date": [], "time": []},
{"date": ["Mon, Oct 3"], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["2:30 pm"]},
{"date": [], "time": []},
{"date": [" "], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["8:00 pm"]},
{"date": [], "time": []},
{"date": [" "], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["8:00 pm"]},
{"date": [], "time": []},
{"date": [" "], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["8:30 pm"]},
{"date": [], "time": []},
{"date": [" "], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["9:00 pm"]},
{"date": [], "time": []},
{"date": [" "], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["10:00 pm"]},
{"date": [], "time": []},
{"date": [" "], "time": []},
{"date": [], "time": []},
{"date": [], "time": ["10:00 pm"]},
{"date": [], "time": []}
]
  

Первый dict содержит правильные данные в правильном порядке, но не сопоставлен. Следующие дикты неправильно сопоставили данные в первом дикте. Я попытался использовать оператор while для удаления новых строк, но безуспешно.

Есть предложения? Я создал это, используя учебное пособие по Scrapy. Я знаю, что в конечном итоге мне нужно будет вставить правильные даты.

Ответ №1:

Вероятно, вы хотите быть более конкретным в выбранной таблице и строках.

Взгляните на HTML для начала расписания:

    <div id="scheduleMain" style="margin:0 5px 0 0!important;">
   <table border="0" cellpadding="0" cellspacing="0" class="genSchedTable tvindex">
      <tr class="header">
         <td colspan="4">NATIONAL TV SCHEDULE - 2016-17</td>
      </tr>
      <tr class="title">
         <td class="date">Date</td>
         <td class="game">Teams</td>
         <td class="time">Time (ET)</td>
         <td class="natTV">Network</td>
      </tr>
      <tr>
         <td class="dt">Mon, Oct 3</td>
         <td class="gm"><a href="/thunder">Oklahoma City</a> @ <a href="/real_madrid">Real Madrid</a><br>Preseason

         </td>
         <td class="tm">2:30 pm</td>
         <td class="ntv"><img border="0" src="http://i.cdn.turner.com/nba/nba/images/shrinkee_NBATV.gif"><img border="0" src="http://i.cdn.turner.com/nba/nba/images/shrinkee_NBAC.gif"></td>
      </tr>
      ...
  

Вы можете видеть, что таблица, которую вы ищете, находится внутри a <div id="scheduleMain"> .

И вы должны выбирать строки таблицы ( <tr> ), а не ячейки таблицы в вашем цикле for, и на каждой итерации цикла выделять ячейки для времени и даты:

 def parse(self, response):
    for game in response.css('#scheduleMain > table tr:nth-child(n 3)'):
        yield {
            'date': game.css('td.dt::text').extract(),
            'time': game.css('td.tm::text').extract(),
        }
  

tr:nth-child(n 3) используется для выбора строк 3, 4, 5… (первые 2 строки являются заголовками)

Комментарии:

1. конец строки response.css должен заключаться в кавычки. Это работает намного лучше, большое спасибо за вашу помощь!

2. Правильно! извините за опечатку