Пряный Тиаоцзюнь написал рептилий 1 [цена на ракушку ползет]

Python
Пряный Тиаоцзюнь написал рептилий 1 [цена на ракушку ползет]

Я несколько дней учился писать краулер на питоне, давайте напишем небольшой краулер, чтобы проверить результаты обучения. Эта статья подходит для еды Xiaobai, всем хорошо провести время~

Совет: Эта статья предназначена только для обучения и общения, не используйте ее в незаконных целях! ! !

1. Веб-анализ

Чтобы сканировать информацию о вторичном жилье в Шицзячжуане с Shell.net, сначала откройте ссылку.https://sjz.ke.com/ershoufang/.在这里插入图片描述Без добавления фильтров всего было найдено 42 817 домов. Нажимаем на вторую страницу, после чего ссылка просмотра становитсяhttps://sjz.ke.com/ershoufang/pg2/. Поэтому можно найти/pg{i}, я - номер страницы. После того, как учитель физкультуры Латиаоцзюнь преподавал математику, я подсчитал, что на каждой странице 30 страниц, и можно выбрать максимум 100 страниц.在这里插入图片描述Таким образом, вы можете просканировать до 3 000 наборов информации о свойствах, что все еще далеко от 40 000, указанных выше, поэтому попробуйте поместитьpg{i}Если я искусственно изменил его, нажмите Enter, чтобы запросить его.

https://sjz.ke.com/ershoufang/pg200/

https://sjz.ke.com/ershoufang/pg300/

Обнаружено, что эти два запроса возвращают одни и те же данные информации о недвижимости. Это вся информация на странице 100, так что делайте выводы.通过贝壳网web端,查看某一条件下的房产信息,最多可以查看3000套. Блин, можно купить максимум 3000 наборов.Очень неудобно иметь деньги и не иметь возможности их потратить~ Побег :)~~

在这里插入图片描述Итак, мы добавляем некоторые условия, например, тот, у которого всего пять комнат, и тот, у которого 2 комнаты. запрос~在这里插入图片描述обнаружил, что ссылка сталаhttps://sjz.ke.com/ershoufang/pg2mw1l2/.mw1l2Это дело надо фильтровать. Видя, что наборов всего 2399, Ок, полезем.

2. Засучите рукава и напишите код

Хотя воробей маленький и цельный, эта рептилия состоит из трех частей.爬取,解析,储存.

Ползание

Сканировать и использоватьrequestsБиблиотеки, чем встроенные библиотеки PythonurllibГораздо проще в использовании.

import requests

def get_a_page(url):
    result = requests.get(url)
    print(result.text)
    
if __name__ == '__main__':
    for i in range(1, 101):
        get_a_page(f'https://sjz.ke.com/ershoufang/pg{i}mw1l2/')

Цикл for печатает возвращенные данные и не обнаруживает проблем. На самом деле, было бы хорошо, если бы я зациклился на 81. Ведь мы знаем, что наборов всего меньше 2400.

Разобрать

Разбор использованияpyquery, эта библиотека похожа на Jquery в использовании. полный API,https://pythonhosted.org/pyquery/api.html. Также есть библиотека разбора `bs4, попробуйте в следующий раз.

在这里插入图片描述

Найдите показания, как показаноulвнутри одногоdivМы можем получить нужные нам данные.

import requests
from pyquery import PyQuery as pq
import json

def get_a_page(url):
    result = requests.get(url)
    doc = pq(result.text) 
    ul = doc('.sellListContent')
    divs = ul.children('.clear .info.clear').items()
    for div in divs:
        count += 1
        title = div.children('.title a').text()
        place = div.children('.address .flood .positionInfo a').text()
        msg = div.children('.address .houseInfo').text()
        price = div.children('.address .priceInfo .totalPrice span').text()
        per_meter = div.children('.address .priceInfo .unitPrice').attr('data-price')
        dict = {
            'title': title,
            'place': place,
            'msg': msg,
            'price': price,
            'per_meter': per_meter
        }
        print(str(count) + ':' + json.dumps(dict, ensure_ascii=False))

Код такой же, как указано выше, pyquerychildrenСпособ состоит в том, чтобы найти подтег,findМетод заключается в том, чтобы найти метку-потомка, здесь нам нужно только найти следующее поколение. затем пройтиtextНайдите текст, содержащийся в этикетке.attrсостоит в том, чтобы получить содержимое атрибута, потому что этоper_meterЕго относительно просто получить из атрибута, а содержание на этикетке также включает «юань/квадратный метр».

хранить

На этот раз мы храним прямо вcsv, похожий наexcelформат файла. использованиеpandasбиблиотека.

Полный код выглядит следующим образом:

import requests
from pyquery import PyQuery as pq
import json
import pandas as pd

columns = ['title', 'msg', 'price', 'per_meter']

# 爬取某网页
def get_a_page(url):
    result = requests.get(url)
    doc = pq(result.text)
    ul = doc('.sellListContent')
    divs = ul.children('.clear .info.clear').items()
    count = 0
    titles = []
    places = []
    msgs = []
    prices = []
    per_meters = []
    for div in divs:
        count += 1
        title = div.children('.title a').text()
        place = div.children('.address .flood .positionInfo a').text()
        msg = div.children('.address .houseInfo').text()
        price = div.children('.address .priceInfo .totalPrice span').text()
        per_meter = div.children('.address .priceInfo .unitPrice').attr('data-price')
        dict = {
            'title': title,
            'place': place,
            'msg': msg,
            'price': price,
            'per_meter': per_meter
        }
        titles.append(title)
        places.append(place)
        msgs.append(msg)
        prices.append(price)
        per_meters.append(per_meter)
        print(str(count) + ':' + json.dumps(dict, ensure_ascii=False))
    datas={
        'title': titles,
        'place': places,
        'msg': msgs,
        'price': prices,
        'per_meter': per_meters
    }
    df = pd.DataFrame(data=datas, columns=columns)
    df.to_csv('sjz.csv', mode='a', index=False, header=False)

if __name__ == '__main__':
    for i in range(1, 101):
        get_a_page(f'https://sjz.ke.com/ershoufang/pg{i}mw1l2/')

мультипрогресс

потому чтоget_a_pageФункция должна запускаться 100 раз, что немного медленно, поэтому используйте несколько процессов, чтобы ускорить скорость. Пожалуйста, скопируйте эту часть кода напрямую.

Измените основную функцию на следующую

from multiprocessing.pool import Pool

if __name__ == '__main__':
    pool = Pool(5)
    group = ([f'https://sjz.ke.com/ershoufang/pg{x}mw1l2/' for x in range(1, 101)])
    pool.map(get_a_page,group)
    pool.close()
    pool.join()

3. Конец

Обратите внимание на следующие эффекты:

在这里插入图片描述Эффект в порядке. Некоторые люди скажут, почему бы не разделить информацию msg и хранить этажи, комнаты и залы, возраст здания и т. д. отдельно. В начале я так и сделал, и обнаружил, что элементы данных msg не требуются.Некоторые домовладельцы возраста здания, этажа и т. д. не заполнили их, поэтому они просто взяли их все.

Это конец первого сканера Латиао Цзюня. Хотя это просто, это все же немного удовлетворяет, когда это написано. В будущем я продолжу изучать поисковые роботы и буду вести блоги. Друзья, ставьте лайк и уходите~