используя scrapy для извлечения нескольких отдельных записей из одной таблицы - PullRequest
0 голосов
/ 12 ноября 2018

Я новичок в python и в целом, и пытаюсь использовать scrapy для извлечения данных с веб-сайта. Проблема в том, что все данные, которые мне нужны, находятся в одной таблице, и многие ее элементы имеют одинаковые теги. HTML выглядит так:

<table cellpadding="10"><tr><td valign="top">
</td><td><br>
<br><br><big><b>1-555-555-1111</b></big>
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LAST, FIRST MIDDLE
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Residence address:</b> 1234 street rd ,  , CITY,   12345
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sex: M
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Race: Black, not Hispanic
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Birth date: 16 January 1968
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Voter ID number: 111111111
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visit the <a href="https://webpage.html">Detail Page of LAST FIRST MIDDLE</a>
<br><br><big><b>1-555-555-1112</b></big>
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BLAST, BFIRST BM.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Residence address:</b> 1234   ANOTHER ST ,  #2-213, CITY,   12345
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sex: F
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Race: White, not Hispanic
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Birth date: 18 December 1933
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Voter ID number: 111111112
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visit the <a href="https://webpage.html">Detail Page of LAST FIRST MIDDLE</a>'
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BBLAST, BBFIRST BBM.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Mailing address:</b> PO BOX 1323, CITY, ST 12345
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Residence address:</b> 1234   ANOTHER ST ,  #2-213, CITY, ST  12345
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sex: F
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Race: White, not Hispanic
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Birth date: 18 December 1933
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Voter ID number: 111111113
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Visit the <a href="https://webpage.html">Detail Page of LAST FIRST MIDDLE</a>'

Мне нужно извлечь данные и иметь возможность выводить их в файл .csv. Мне нужно иметь эти данные в CSV с каждым человеком в их собственном ряду. У меня возникли проблемы, потому что я не знаю, как извлечь его и сохранить его в порядке из-за того, что некоторые записи имеют более одного человека на один номер телефона, и в этих записях номер телефона не печатается для каждого человека , только однажды. Лица, прикрепленные к этому номеру, указаны в одной записи. Также иногда есть поле почтового адреса и поле адреса проживания.

Мне просто нужно убедиться, что при извлечении данных поле номера телефона правильно заполнено для лиц, которые делят номер с другим человеком, и мне нужно убедиться, что есть пустое поле для почтового адреса для записей там нет отдельного адреса.

Когда я пытался что-то вытащить сам, я могу извлечь данные, но они неправильно сохраняют записи с правильным человеком, потому что, как только он попадает в запись с более чем одним человеком в разделе телефонных номеров, он делает их имена все от одного номера телефона. В настоящее время у меня есть следующий код, написанный только для того, чтобы попытаться извлечь число и DOB:

import scrapy
class NumspiderSpider(scrapy.Spider):
    name = 'numspider'
    allowed_domains = ['scraped.site']
    start_urls = ['https://scraped.site']
    def parse(self, response):
        numbers = response.xpath('//td[2]/big/b/text()').extract()
        dob = response.xpath(".//td[2]/following::text()[contains(., 'Birth date')]").extract()
    yield {'Number': numbers, 'DOB': dob}

Кроме того, это, к сожалению, имеет дополнительную проблему с тем, чтобы тянуть вещи, которые я не хочу, например, мои дни рождения выглядят как u'\xa0\xa0\xa0\xa0\xa0Birth date: 16 January 1968\n, а мои числа выглядят так u'1-555-555-1111'. Когда я получаю эту информацию в свой последний CSV, я хочу, чтобы она читала 16 January 1968 и 16 January 1968

1 Ответ

0 голосов
/ 12 ноября 2018

Я тоже не хочу, чтобы мои дни рождения выглядели как u '\ xa0 \ xa0 \ xa0 \ xa0 \ xa0 Дата рождения: 16 января 1968 года \ n и мои цифры выглядят так: u'1-555-555-1111 ». Когда я получу эту информацию в свой последний CSV, я хочу, чтобы она читалась 16 января 1968 года и 16 января 1968 года

Эту часть легко решить: dob = map(lambda x: x.strip(), dob), поскольку \xa0 считается "пробелом" и, следовательно, удаляется со своим другом \n. Вы также можете убить Birth date:: map(lambda x: re.sub(r'Birth date:\s*', '', x.strip()), dob)

Однако, чтобы получить более широкий ответ на ваш вопрос, я хотел бы предложить на ваше рассмотрение, что на самом деле проблема не в HTML, а в том, что текстовый формат скрыт в HTML. Эта ситуация выглядит так же, как если бы они обернули весь этот текст в <pre>: нет селектора, который будет «достигать» в <pre>.

Однако, поскольку это линейно-ориентированный формат, вы можете использовать некоторые удачно расположенные разбиения, чтобы разделить их на основные записи детали, основанные на отступе и последнем тексте записи детали. Я на самом деле очень разочарован тем, что string(//td[2]) не сохранил разделение <br><br> между записями деталей, но c'est la vie .

def parse(self, response):
    the_text = response.xpath("string(//td[2])").extract_first().replace("\xa0", " ").lstrip()
    # kill the leading "\n" entry and split on flush phone numbers
    records = list(filter(lambda x: len(x) > 0, re.split(r'(?m)^([0-9-]+)$', the_text)))
    for i in range(0, len(records), 2):
        phone = records[i]
        rest = records[i+1]
        details = re.split(r'(?m)^\s+Visit the Detail Page.*$', rest)
        for det in details:
            print('detail[ {} ] := {}'.format(phone, det))
            # etc etc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...