Xiaobai изучает поисковый робот Python (25): сканирование информации о запасах

Python

Жизнь слишком коротка, я использую Python

Предыдущий портал:

Xiaobai изучает поисковый робот Python (1): начало

Xiaobai изучает поисковый робот Python (2): предварительная подготовка (1) установка базовой библиотеки классов

Xiaobai Learns Python Crawler (3): Предварительная подготовка (2) Введение в основы Linux

Xiaobai Learns Python Crawler (4): Предварительная подготовка (3) Введение в основы Docker

Xiaobai Learns Python Crawler (5): предварительная подготовка (4) Основы базы данных

Xiaobai изучает краулер Python (6): предварительная подготовка (5) установка фреймворка краулера

Xiaobai изучает поисковый робот Python (7): основы HTTP

Xiaobai изучает поисковый робот Python (8): основа веб-страницы

Xiaobai изучает краулер Python (9): основы краулера

Xiaobai изучает поисковый робот Python (10): сеанс и файлы cookie

Xiaobai изучает поисковый робот Python (11): основы использования urllib (1)

Xiaobai изучает поисковый робот Python (12): основы использования urllib (2)

Xiaobai изучает поисковый робот Python (13): основы использования urllib (3)

Xiaobai изучает поисковый робот Python (14): основы использования urllib (4)

Xiaobai изучает поисковый робот Python (15): базовое использование urllib (5)

Xiaobai изучает краулер Python (16): реальная битва urllib с ползающей сестринской картой

Xiaobai изучает поисковый робот Python (17): основы использования запросов

Xiaobai изучает поисковый робот Python (18): запрашивает расширенную операцию

Xiaobai изучает поисковый робот Python (19): основные операции Xpath

Xiaobai изучает поисковый робот Python (20): расширенный Xpath

Xiaobai изучает поисковый робот Python (21): библиотека синтаксического анализа Beautiful Soup (1)

Xiaobai изучает поисковый робот Python (22): анализ библиотеки Beautiful Soup (часть 2)

Xiaobai изучает поисковый робот Python (23): введение в синтаксический анализ библиотеки pyquery

Сяобай изучает поисковый робот Python (24): рейтинг фильмов Douban за 2019 год

введение

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

Данная тема является статьей, написанной первой после написания кода, ее однозначно можно использовать для анализа элементов страницы, а также необходим определенный анализ загрузки данных сайта для получения окончательных данных, и два данные, которые нашел редактор Источник не имеет ограничений доступа по IP, и качество гарантировано Это, безусловно, отличный выбор для Xiaobai для практики.

Торжественно заявляем:Эта статья предназначена только для учебных целей.

анализировать

Прежде всего, чтобы сканировать данные об акциях, вы должны сначала узнать, какие акции есть.Здесь Xiaobian нашел веб-сайт со списком кодов акций: https://hq.gucheng.com/gpdmylb.html.

Включите режим разработчика Chrome и выберите тикеры один за другим. Конкретный процесс здесь не публикуется, студенты могут реализовать его самостоятельно.

Мы можем хранить все символы акций в виде списка, а остальное — найти веб-сайт и циклически вынимать данные каждой акции.

Редактор этого сайта уже нашел его, это стрит-флеш, ссылка: http://stockpage.10jqka.com.cn/000001/.

Предположительно все умные студенты обнаружили, что в этой ссылке000001Это символ тикера.

Затем нам нужно только соединить эту ссылку, чтобы постоянно получать нужные данные.

настоящий бой

Прежде всего, давайте представим библиотеку запросов и библиотеку синтаксического анализа, используемые в этом реальном бою: Requests и pyquery. Хранилище данных, наконец, приземлилось в Mysql.

Получить список символов тикера

Первым шагом, конечно же, является создание списка символов акций.Давайте сначала определим метод:

def get_stock_list(stockListURL):
    r =requests.get(stockListURL, headers = headers)
    doc = PyQuery(r.text)
    list = []
    # 获取所有 section 中 a 节点,并进行迭代
    for i in doc('.stockTable a').items():
        try:
            href = i.attr.href
            list.append(re.findall(r"\d{6}", href)[0])
        except:
            continue
    list = [item.lower() for item in list]  # 将爬取信息转换小写
    return list

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

Получить подробные данные

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

http://qd.10jqka.com.cn/quote.php?cate=real&type=stock&callback=showStockDate&return=json&code=000001

Что касается того, как его найти, то в этот раз редактор не будет говорить об этом. Я все же надеюсь, что все студенты, которые хотят изучать рептилий, смогут сделать это сами, пойти и найти его. После еще нескольких поисков вы, естественно, найдете путь.

Теперь, когда интерфейс данных доступен, давайте посмотрим на возвращаемые данные:

showStockDate({"info":{"000001":{"name":"\u5e73\u5b89\u94f6\u884c"}},"data":{"000001":{"10":"16.13","8":"16.14","9":"15.87","13":"78795234.00","19":"1262802470.00","7":"16.12","15":"40225508.00","14":"37528826.00","69":"17.73","70":"14.51","12":"5","17":"945400.00","264648":"0.010","199112":"0.062","1968584":"0.406","2034120":"9.939","1378761":"16.026","526792":"1.675","395720":"-948073.000","461256":"-39.763","3475914":"313014790000.000","1771976":"1.100","6":"16.12","11":""}}})

Очевидно, что этот результат не является стандартными данными json, но это данные стандартного формата, возвращаемые JSONP.Здесь мы сначала обрабатываем голову и хвост, превращаем их в стандартные данные json, а затем анализируем их по данным на этой странице, и наконец Запишите проанализированное значение в базу данных.

def getStockInfo(list, stockInfoURL):
    count = 0
    for stock in list:
        try:
            url = stockInfoURL + stock
            r = requests.get(url, headers=headers)
            # 将获取到的数据封装进字典
            dict1 = json.loads(r.text[14: int(len(r.text)) - 1])
            print(dict1)

            # 获取字典中的数据构建写入数据模版
            insert_data = {
                "code": stock,
                "name": dict1['info'][stock]['name'],
                "jinkai": dict1['data'][stock]['7'],
                "chengjiaoliang": dict1['data'][stock]['13'],
                "zhenfu": dict1['data'][stock]['526792'],
                "zuigao": dict1['data'][stock]['8'],
                "chengjiaoe": dict1['data'][stock]['19'],
                "huanshou": dict1['data'][stock]['1968584'],
                "zuidi": dict1['data'][stock]['9'],
                "zuoshou": dict1['data'][stock]['6'],
                "liutongshizhi": dict1['data'][stock]['3475914']
            }
            cursor.execute(sql_insert, insert_data)
            conn.commit()
            print(stock, ':写入完成')
        except:
            print('写入异常')
            # 遇到错误继续循环
            continue

Здесь мы добавляем обработку исключений, потому что в этот раз сканируется много данных, и очень вероятно, что по какой-то причине будет выброшено исключение.Конечно, мы не хотим прерывать сбор данных, когда возникает исключение, поэтому добавьте сюда обработку исключений, чтобы продолжить сбор данных.

полный код

Мы немного инкапсулируем код, чтобы завершить этот реальный бой.

import requests
import re
import json
from pyquery import PyQuery
import pymysql

# 数据库连接
def connect():
    conn = pymysql.connect(host='localhost',
                           port=3306,
                           user='root',
                           password='password',
                           database='test',
                           charset='utf8mb4')

    # 获取操作游标
    cursor = conn.cursor()
    return {"conn": conn, "cursor": cursor}

connection = connect()
conn, cursor = connection['conn'], connection['cursor']

sql_insert = "insert into stock(code, name, jinkai, chengjiaoliang, zhenfu, zuigao, chengjiaoe, huanshou, zuidi, zuoshou, liutongshizhi, create_date) values (%(code)s, %(name)s, %(jinkai)s, %(chengjiaoliang)s, %(zhenfu)s, %(zuigao)s, %(chengjiaoe)s, %(huanshou)s, %(zuidi)s, %(zuoshou)s, %(liutongshizhi)s, now())"

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}

def get_stock_list(stockListURL):
    r =requests.get(stockListURL, headers = headers)
    doc = PyQuery(r.text)
    list = []
    # 获取所有 section 中 a 节点,并进行迭代
    for i in doc('.stockTable a').items():
        try:
            href = i.attr.href
            list.append(re.findall(r"\d{6}", href)[0])
        except:
            continue
    list = [item.lower() for item in list]  # 将爬取信息转换小写
    return list


def getStockInfo(list, stockInfoURL):
    count = 0
    for stock in list:
        try:
            url = stockInfoURL + stock
            r = requests.get(url, headers=headers)
            # 将获取到的数据封装进字典
            dict1 = json.loads(r.text[14: int(len(r.text)) - 1])
            print(dict1)

            # 获取字典中的数据构建写入数据模版
            insert_data = {
                "code": stock,
                "name": dict1['info'][stock]['name'],
                "jinkai": dict1['data'][stock]['7'],
                "chengjiaoliang": dict1['data'][stock]['13'],
                "zhenfu": dict1['data'][stock]['526792'],
                "zuigao": dict1['data'][stock]['8'],
                "chengjiaoe": dict1['data'][stock]['19'],
                "huanshou": dict1['data'][stock]['1968584'],
                "zuidi": dict1['data'][stock]['9'],
                "zuoshou": dict1['data'][stock]['6'],
                "liutongshizhi": dict1['data'][stock]['3475914']
            }
            cursor.execute(sql_insert, insert_data)
            conn.commit()
            print(stock, ':写入完成')
        except:
            print('写入异常')
            # 遇到错误继续循环
            continue
def main():
    stock_list_url = 'https://hq.gucheng.com/gpdmylb.html'
    stock_info_url = 'http://qd.10jqka.com.cn/quote.php?cate=real&type=stock&callback=showStockDate&return=json&code='
    list = get_stock_list(stock_list_url)
    # list = ['601766']
    getStockInfo(list, stock_info_url)

if __name__ == '__main__':
    main()

достижение

В итоге редактору потребовалось около 15 минут, чтобы успешно захватить 4600+ фрагментов данных, и результат не будет отображаться.

образец кода

Все редакторы кода из этой серии будут размещены в репозиториях управления кодом Github и Gitee для вашего удобства.

Пример кода — Гитхаб

Пример кода — Gitee

Если моя статья была вам полезна, отсканируйте код и подпишитесь на официальный аккаунт автора: Получите последние новости о галантерейных товарах :)