#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. Извините, я думаю, что плохо сформулировал вопрос. Я думаю, что это хорошая идея, но моя проблема связана не столько со всеми столбцами, сколько с заголовками, содержащими название отдела. Что мне нужно, так это настроить синтаксический анализ так, чтобы он возвращал заголовок отдела в качестве переменной отдела для каждого сотрудника под ним, пока он не достигнет нового заголовка отдела.