Scrapy сканирует информацию о вторичном жилье + визуальный анализ данных

рептилия анализ данных искусственный интеллект Scrapy

Добавить Автора

Публичный аккаунт WeChat:PythonНаука о данных

Знать: https://zhuanlan.zhihu.com/pypcfx


В этой статье представленscrapyРеальный проект боевого обходчика и простой анализ просканированной информации. цель北京二手房信息, начните анализ ниже.

Анализ структуры веб-страницы

Информация веб-сайта Anjuke используется в качестве источника информации о вторичном жилье. Нажмите прямо, чтобы перейти на страницу с информацией о бывшем в употреблении жилье.

Информация о жилье на странице:

Подробности после перехода по ссылке:

Блогер не использовал субрегиональное сканирование, блогер сразу просканировал все, а затем завершил цикл следующей страницы. Шаги очень просты, а именно:

  1. Сначала просмотрите все подробные ссылки на подержанное жилье на каждой странице, чтобы
  2. Запрашивать каждую подробную ссылку, просканированную для анализа информации о жилье
  3. После завершения парсинга запросить ссылку на следующую страницу
  4. Вернитесь к шагу один цикл, пока возвращаемое содержимое не станет пустым

Реализация кода Scrapy

определение структуры данных

Scrapyметаданные вfieldФактически он унаследован от Python.字典Тип данных очень удобен в использовании, блогер напрямую определяет информацию о нескольких домах, как показано в следующем коде. Конечно, есть и расширенное использование, сitemloaderПрисоединяйсяprocessor, здесь можно использовать только простое определение.

class AnjukeItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()

    price = scrapy.Field()
    mode = scrapy.Field()
    area = scrapy.Field()
    floor = scrapy.Field()
    age = scrapy.Field()
    location = scrapy.Field()
    district = scrapy.Field()
    pass

Поисковый анализ

  • определяет наследованиеScrapyВстроенные рептилииSpider.
  • Тогда самое главноеname, которая проходит через всюScrapyвсегда, вы увидите его эффект позже.
  • start_urls— это список начальных URL-адресов запроса, также может быть несколько начальных URL-адресов, здесь только один.
  • потому чтоScrapyизSpiderКласс используется по умолчаниюRequestзапрос, поэтому выберите не переопределять здесьRequest, используется запрос по умолчанию, и в запросе вызывается функция обратного вызова синтаксического анализа.
  • разборная частьScrapyпередовойselectorселекторxpathразобрать.

parseВ запросе функции их дваyield, что означает генератор.

  • ПервыйyieldВернуться к ссылке на следующую страницу для каждой страницыnext_pageurl.
  • второйyieldВернитесь на каждую страницу, чтобы просмотреть все ссылки на подробные сведения о жилье, и сноваRequestЗапросите продолжение, затем вызовите следующую функцию обратного вызоваparse_detail.

Если процесс запроса слишком быстрый, он запросит ввод验证码, скорость запроса здесь замедлена, а проверочная часть пока не обрабатывается (введено позже).

class AnjukeSpider(scrapy.Spider):
    name = 'anjuke'
    # custom_settings = {
    #     'REDIRECT_ENABLED': False
    # }
    start_urls = ['https://beijing.anjuke.com/sale/']

    def parse(self, response):
        # 验证码处理部分
        pass

        # next page link
        next_url = response.xpath(
            '//*[@id="content"]/div[4]/div[7]/a[7]/@href').extract()[0]
        print('*********' + str(next_url) + '**********')
        if next_url:
            yield scrapy.Request(url=next_url,
                                 callback=self.parse)

        # 爬取每一页的所有房屋链接
        num = len(response.xpath(
            '//*[@id="houselist-mod-new"]/li').extract())

        for i in range(1, num + 1):
            url = response.xpath(
                '//*[@id="houselist-mod-new"]/li[{}]/div[2]/div[1]/a/@href'
                    .format(i)).extract()[0]
            yield scrapy.Request(url, callback=self.parse_detail)

parse_detailиспользуется в функции обратного вызоваitemloaderРазобратьitemsинформацию о жилье и возвращает информацию, содержащуюitem.

    def parse_detail(self, response):
        houseinfo = response.xpath('//*[@class="houseInfo-wrap"]')
        if houseinfo:
            l = ItemLoader(AnjukeItem(), houseinfo)

            l.add_xpath('mode', '//div/div[2]/dl[1]/dd/text()')
            l.add_xpath('area', '//div/div[2]/dl[2]/dd/text()')
            l.add_xpath('floor', '//div/div[2]/dl[4]/dd/text()')
            l.add_xpath('age', '//div/div[1]/dl[3]/dd/text()')
            l.add_xpath('price', '//div/div[3]/dl[2]/dd/text()')
            l.add_xpath('location', '//div/div[1]/dl[1]/dd/a/text()')
            l.add_xpath('district', '//div/div[1]/dl[2]/dd/p/a[1]/text()')

            yield l.load_item()

Очистка данных

Из-за обходаitemsДанные беспорядочные, есть разные\n,\tзнак равенства, поэтому вpipelinesДля простой очистки используйте正则表达式Реализация, код выглядит следующим образом:

import re

def list2str(value):
    new = ''.join(value).strip()
    return new

class AnjukePipeline(object):
    def process_item(self, item, spider):
        area = item['area']
        price = item['price']
        loc = item['location']
        district = item['district']
        mode = item['mode']
        age = item['age']
        floor = item['floor']

        modes = list2str(mode)
        item['area'] = int(re.findall(r'\d+', list2str(area))[0])
        item['age'] = int(re.findall(r'\d+', list2str(age))[0])
        item['floor'] = list2str(floor)
        item['location'] = list2str(loc)
        item['district'] = list2str(district)
        item['price'] = int(re.findall(r'\d+', list2str(price))[0])
        item['mode'] = modes.replace('\t', '').replace('\n', '')

        return item

не забудьтеsettingвнутренние настройкиpipelineпараметр.

ITEM_PIPELINES = {
   'anjuke.pipelines.AnjukePipeline': 300,
}

запуск командной строки

Мы хотим вывести очищенные данные в файл,csvилиjson, мы выводим здесь какcsv格式документ.

В Scrapy нужен только одинcommandКоманду можно завершить, введите командную строку под файлом проекта:

scrapy crawl anjuke -o items.csv

в командной строкеanjukeЭто то, что мы определили в началеname.

Начать сканирование:

Анализ визуализации данных

После сканирования данных мы получаемcsvФайл открывается и отображается следующим образом:

Затем мы будем использоватьjupyter notebookДля анализа данных код выглядит следующим образом:

Краткий анализ регионов每平米二手房单价а также各大区二手房数量, данные только частичные, блогер не ждал, пока будут просканированы все данные, это только для справки. Конечно, более сложный анализ данных и машинное обучение также могут быть использованы для прогнозирования цен на жилье в соответствии с реальной ситуацией.

Схема эффекта выглядит следующим образом:

##Суммировать Эта статья — всего лишь простой пример, полноценный и эффективный краулер еще многое предстоит улучшить.

  • присоединиться к агентуip池
  • scrapdРазвертывание распределенного сканера
  • Особенности инкрементного обходчика
  • .... Они будут введены медленно в последующем, законченном.

Обратите внимание на публичный аккаунт WeChatPython数据科学, перенесет вас в мир данных.