Как перебирать / анализировать строки таблицы по порядку, не переходя к следующему экземпляру переменной?

#python #for-loop #html-table #scrapy #header

#python #для цикла #html-таблица #scrapy #заголовок

Вопрос:

Я новичок во всем этом, поэтому, пожалуйста, потерпите меня. У меня есть некоторые знания Java, но я решил, что недавно хотел научиться использовать scrapy и python.

В качестве проекта, который поможет мне начать работу, я пытаюсь написать spider, который будет очищать каталоги онлайн-контактов, которые я затем импортирую в csv. Сейчас я сосредоточен на каталогах, которые отформатированы как таблица .aspx.

На данный момент я добился того, что он работает именно так, как я хочу, за исключением заголовков. В каталоге отделы разделены тегами th, содержащими название каждого отдела, и все в этом отделе перечислены ниже.

Моя цель — настроить его так, чтобы выходные данные были отформатированы следующим образом: [Department, Name, Title, Email, Phone#]

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

Итак, предполагая Name1 , что и Name2 находятся в Department1 , а не в выводе, чтобы Name2 выглядеть так: [Department1, Name2, Title, Email, Phone#] вывод выглядит так, потому что селектор для заголовка отдела перешел к следующему экземпляру этого xpath . [Department2, Name2, Title, Email, Phone#] потому что это вторая запись контакта, а department — вторая запись отдела.

Ниже приведен мой анализ.

Он настроен на перебор строк таблицы, и для каждой строки он будет собирать контактную информацию из заданного xpath.

Я попытался написать оператор xpath contains, чтобы проверить, был ли сначала xpath заголовка, но это не сработало и в конечном итоге напечатало только заголовки.

 for url in urls:
        yield scrapy.Request(url=url, callback=self.parse)

  def parse(self, response):
      rows = response.xpath('//table/tbody/tr')
      for i in range(0, len(rows)-1):

          yield {
                  'header' : rows.xpath('//tr[@class="sidearm-staff-category "]/th//text()').extract()[i],
                  'col1' : rows.xpath('//th/a[1]//text()').extract()[i].strip(),
                  'col2' : rows.xpath('//td[1]//text()').extract()[i].strip(),
                  'col3' : rows.xpath('//td[2]/a//text()').extract()[i].strip(),
                  'col4' : rows.xpath('//td[3]/a//text()').extract()[i].strip(),
                  }
  

Вот мой вывод (для конфиденциальности тех, кто находится в каталоге, я заменил их адреса электронной почты и номера телефонов).

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

 {'header': 'Athletic Administration', 'col1': 'Laura  Courtley-Todd', 'col2': 'Director of Athletics', 'col3': 'email', 'col4': 'phone'}

2019-04-12 14:11:44 [scrapy.core.scraper] DEBUG: Scraped from <200 https://stubobcats.com/staff.aspx>
{'header': 'Athletic Communications', 'col1': 'Dr. Jan  Bell', 'col2': 'Faculty Athletics Representative', 'col3': 'email', 'col4': 'phone'}
  

Ответ №1:

используйте beautiful soup и попробуйте более питонический способ узнать о модуле запросов я не думаю, что xpath следует использовать, когда html упорядочен и элегантен в кавычках, т.Е.: Он находится в организованных таблицах в основном в bs4, функции select, find, find_all могут выполнять свою работу, в запросах не требуется регулярных выражений, узнайте о заголовках, пользовательский агент, заголовок ссылки

 pip install bs4
pip install requests

s=requests.Session()
u='www'
rp=s.get(u,headers=myheaders)
sp=soup(rp.text)
table=sp.find('table')
rows=table.select('tr')
for row in rows:
     print row.text
     a=row.select('a')
     print a['href']
  

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

1. Хорошо, я продолжаю получать «myheaders не определен». Кроме того, как бы мне записать это в spider?

Ответ №2:

Поскольку вы уже используете выбор xpath, возможно, вам удастся избежать использования более конкретных селекторов?:

 cat1 = response.xpath('//*[@data-category-id="1"')
cat2 = response.xpath('//*[@data-category-id="2"')
  

А затем используйте селекторы классов для извлечения типов категорий:

 type1 = cat1.xpath('//*[@class="sidearm-staff-category"]'
type1_members = cat1.xpath('//*[@class="sidearm-staff-member"]'
type1_members.xpath('//td[@headers="col-fullname"]')
  

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

1. Извините, я думаю, что плохо сформулировал вопрос. Я думаю, что это хорошая идея, но моя проблема связана не столько со всеми столбцами, сколько с заголовками, содержащими название отдела. Что мне нужно, так это настроить синтаксический анализ так, чтобы он возвращал заголовок отдела в качестве переменной отдела для каждого сотрудника под ним, пока он не достигнет нового заголовка отдела.