Я новичок во всем этом, поэтому, пожалуйста, потерпите меня. У меня есть некоторые знания 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'}