Итак, я спустился в кроличью нору и перестроил паука в базовый, а не в ползучий. Я не мог понять, почему в наборе правил LinkEctract не перезванивал парсер.
В любом случае я создал функцию cvs_exporter, чтобы лучше управлять выводом. Добавил его и его аргументы в настройки и вуаля.
Паук перемещается по сайту через ту же логику, что и паук "Сканирование", хотя цель указана для URL, а не для широкого сканирования. От "parse_district"> "parse_postions"> наконец до "parse_person", где существуют элементы, которые вы хотите очистить.
blockquote>#stlSpider.py import scrapy from stltoday.items import StltodayItem class StlspiderSpider(scrapy.Spider): name = 'stlSpider' allowed_domains = ['graphics.stltoday.com'] start_urls = ['http://graphics.stltoday.com/apps/payrolls/salaries/teachers/'] def parse(self, response): for href in response.xpath("//th/a/@href").re(".*/teachers/[0-9]+/"): yield scrapy.Request(response.urljoin(href), callback=self.parse_district) def parse_district(self, response): for href in response.xpath("//th/a/@href").re(".*position.*"): yield scrapy.Request(response.urljoin(href), callback=self.parse_position) def parse_position(self, response): for href in response.xpath("//td/a/@href").extract(): yield scrapy.Request(response.urljoin(href), callback=self.parse_person) def parse_person(self, response): item = StltodayItem() name = response.xpath('//p[@class="table__title"]/text()').extract_first() row = response.xpath('//th[@scope="row"]') item["url"] = response.url item["fullname"] = name item["district"] = row.xpath('//th[contains(., "District")]/following-sibling::td/text()').extract_first() item["school"] = row.xpath('//th[contains(., "School")]/following-sibling::td/text()').extract_first() item["degree"] = row.xpath('//th[contains(., "Degree")]/following-sibling::td/text()').extract_first() item["salary"] = row.xpath('//th[contains(., "Salary")]/following-sibling::td/text()').extract_first() item["extcontractpay"] = row.xpath('//th[contains(., "Extended")]/following-sibling::td/text()').extract_first() item["extraduty"] = row.xpath('//th[contains(., "Extra")]/following-sibling::td/text()').extract_first() item["totalpay"] = row.xpath('//th[contains(., "Total")]/following-sibling::td/text()').extract_first() item["yearsindistrict"] = row.xpath('//th[contains(., "Years in district")]/following-sibling::td/text()').extract_first() item["yearsinmoschools"] = row.xpath('//th[contains(., "Years in MO")]/following-sibling::td/text()').extract_first() yield item
Детализировал ... items lol
blockquote>#items.py import scrapy class StltodayItem(scrapy.Item): url = scrapy.Field() fullname = scrapy.Field() district = scrapy.Field() school = scrapy.Field() degree = scrapy.Field() salary = scrapy.Field() extcontractpay = scrapy.Field() extraduty = scrapy.Field() totalpay = scrapy.Field() yearsindistrict = scrapy.Field() yearsinmoschools = scrapy.Field()
Создал модуль "csv_exporter", где вы можете вызвать его, чтобы сделать настройки того, как выводится ваш файл, включая установку разделителей и порядка элементов для вывода
blockquote>#csv_exporter.py _author_ = 'Erick' from scrapy.conf import settings from scrapy.contrib.exporter import CsvItemExporter class MyProjectCsvItemExporter(CsvItemExporter): def __init__(self, *args, **kwargs): delimiter = settings.get('CSV_DELIMITER', ',') kwargs['delimiter'] = delimiter fields_to_export = settings.get('FIELDS_TO_EXPORT', []) if fields_to_export : kwargs['fields_to_export'] = fields_to_export super(MyProjectCsvItemExporter, self).__init__(*args, **kwargs)
Включите экспорт в ваш файл settings.py, здесь вы включаете набор аргументов ins "csv_exporter" - разделитель, который вы хотите использовать, и порядок полей (предметов) для экспорта
blockquote>#settings.py OT_NAME = 'stltoday' SPIDER_MODULES = ['stltoday.spiders'] NEWSPIDER_MODULE = 'stltoday.spiders' FEED_FORMAT = 'csv' FEED_URI = 'tmp/stltoday1.csv' FIELDS_TO_EXPORT = ["url", "fullname", "district", "school", "degree", "salary", "extcontractpay", "extraduty", "totalpay", "yearsindistrict", "yearsinmoschools"] FEED_EXPORTERS = { 'csv': 'stltoday.csv_exporter.MyProjectCsvItemExporter', } # Crawl responsibly by identifying yourself (and your website) on the user-agent #USER_AGENT = 'stltoday (+http://www.yourdomain.com)' # Obey robots.txt rules ROBOTSTXT_OBEY = False ...
Давайте пропустим непосредственно к локализации. Вы сказали бы "aa"> = "ba"? Вероятно, не, но это - то, где это сортирует в Швеции. Кроме того, Вы просто не можете предположить, что можно проигнорировать преобразование регистра на любом языке. Преобразование регистра является явно языковозависимым, при этом наиболее распространенный пример турецкий: верхний регистр я - İ. Нижний регистр я - ı.
Теперь, Ваш DB SQL определяет результат <== и т.д. согласно "порядку сопоставления". Это - определенно конкретный язык. Так, необходимо явно управлять этим для каждого запроса. Турецкий порядок сопоставления поместит тех, которые я - то, где они принадлежат (турецкого языка). Вы не можете полагаться на сопоставление по умолчанию.
Что касается "инкрементной части", не беспокоиться. Придерживайтесь> = и <=.
Поскольку MSSQL видят этот поток: http://bytes.com/forum/thread483570.html.
Для Oracle это зависит от Вашей версии Oracle, поскольку Oracle 10 теперь поддерживает regex (p) как запросы: http://www.psoug.org/reference/regexp.html (ищут regexp_like) и видит эту статью: http://www.oracle.com/technology/oramag/webcolumns/2003/techarticles/rischert_regexp_pt1.html
HTH
Разочаровывающе, функция подстроки Oracle является SUBSTR (), пока это SQL Server это - ПОДСТРОКА ().
Вы могли записать простую обертку вокруг одной или их обоих так, чтобы они совместно использовали то же имя функции + прототип.
Затем можно просто использовать
MY_SUBSTRING(name, 2) >= 'ba' AND MY_SUBSTRING(name, 2) <= 'bi'
или подобный.
Вы могли использовать это...
select * from widget
where name Like 'b[a-i]%'
Это будет соответствовать любой строке, где имя запускается с b, второй символ находится в диапазоне мне, и любые другие символы следуют.
Я думаю, что пошел бы с чем-то простым как добавление высоко сортирующей строки в конец верхней границы. Что-то как:
select * from widgetwhere name >= 'ba' and name <= 'bi'||'~'
Я не уверен, что это пережило бы преобразование EBCDIC хотя
Вы могли также сделать это как это:
select * from widget
where left(name, 2) between 'ba' and 'bi'
Если бы Ваша длина критериев изменяется (когда Вы, казалось, указали в комментарии, Вы уехали), запрос должен был бы иметь длину как вход также:
declare @CriteriaLength int
set @CriteriaLength = 4
select * from widget
where left(name, @CriteriaLength) between 'baaa' and 'bike'