Как зациклить / разобрать строки таблицы по порядку, не пропуская следующий экземпляр переменной? - PullRequest
1 голос
/ 12 апреля 2019

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

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

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

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

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

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

Ниже мой анализ.

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

Я попытался написать оператор содержит xpath, чтобы проверить, был ли сначала 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'}

Ответы [ 2 ]

1 голос
/ 13 апреля 2019

используйте красивый суп и попробуйте более питонический способ узнать о модуле запросов я не думаю, что 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']
0 голосов
/ 12 апреля 2019

Поскольку вы уже используете выбор 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"]')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...