Scrapy с символами новой строки и вложенными тегами - PullRequest
2 голосов
/ 26 января 2012

Отказ от ответственности: плохо знакомый с scrapy.

У меня есть таблица с довольно нерегулярными строками. Основная структура:

<tr>
 <td> some text </td>
 <td> some other text </td>
 <td> yet some text </td>
</tr>

, но иногда (несколько сотен раз) некоторые строки

<tr>
 <td> <p> some text <p> </td>
 <td> <div class="class-whateva"> <p> some other text </p></div> </td>
 <td> <span id="strange-id"> 
  <a href="somelink"> yet some text </a> 
    <span> </td>
</tr>

или другие перестановки из 1 или 2 вложенных «p», «div» и «span» с или без символов обратной строки.

Я позаботился о вложенном «span span» или «p div» или «div span» с помощью условных выражений вида:

for row in allrows:
      if  row.select('td[2]/text()'):
            item['seconditem']=row.select('td[2]/text()').extract()
      elif row.select('td[2]/*/text()'):
            item['seconditem']=row.select('td[2]/*/text()').extract()
      elif row.select('td[2]/*/*/text()'):
            item['seconditem']=row.select('td[2]/*/*/text()').extract()

Теперь у меня два вопроса:

(1) Является ли условный

td[2]/*/*/text()

правильным способом для неправильных вложенных строк?

(2) Я все еще пропускаю все случаи, когда естьвозврат (или перевод строки) перед тегом.Так что, если строка имеет вид:

   <td><div>
      <p>text </p>
   </div></td>

Все, что мой xpath вернет, будет ['\ n'].Любой трюк, чтобы поймать, что после символа новой строки?

Любые советы приветствуются.Спасибо.

1 Ответ

3 голосов
/ 26 января 2012

Вы можете использовать функцию string() в выражении XPath, чтобы получить все внутренние текстовые узлы в одной строке:

# nested.html - your second html snippet
# $scrapy shell "nested.html" 

In [1]: row = hxs.select('//tr')

In [2]: row.select('td[2]').select('string()').extract()
Out[2]: [u'   some other text  ']

In [3]: row.select('td[2]').select('string()').extract()[0]
Out[3]: u'   some other text  '

In [4]: row.select('td[3]').select('string()').extract()[0]
Out[4]: u'  \r\n   yet some text  \r\n     '

или //text(), чтобы получить все внутренние text узлы:

In [5]: row.select('td[3]//text()').extract()
Out[5]: [u' \r\n  ', u' yet some text ', u' \r\n    ', u' ']

И ''.join(...) для получения строки:

In [6]: ''.join(row.select('td[3]//text()').extract())
Out[6]: u' \r\n   yet some text  \r\n     '
...