Нет таланта, я написал краулер данных куплетов Весеннего фестиваля в 30 строк кода

TensorFlow рептилия
Нет таланта, я написал краулер данных куплетов Весеннего фестиваля в 30 строк кода

PK Creative празднует Китайский Новый год. Я участвую в "Творческом конкурсе Весеннего фестиваля". Подробнее см.:Творческий конкурс "Праздник весны"

1. Происхождение

Предложение в начале предназначено для Nuggets, а на других платформах всегда есть слоган. Следующее предложение принадлежит мне, и у меня всегда был лозунг:

У меня два увлечения, одно — традиционная культура, другое — высокие технологии.

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

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

Вход — это верхнее звено ручного ввода, а Выход — это нижнее звено, автоматически заданное машиной.

Input: <start> 神 州 万 里 春 光 美 <end> [2, 61, 27, 26, 43, 4, 20, 78, 3] 
Output:<start> 祖 国 两 制 好 事 兴 <end> [2, 138, 11, 120, 428, 73, 64, 46, 3]

Input:  <start> 爆 竹 迎 新 春 <end> [2, 167, 108, 23, 9, 4, 3]
Output: <start> 瑞 雪 兆 丰 年 <end> [2, 92, 90, 290, 30, 8, 3]

Input:  <start> 金 牛 送 寒 去 <end> [2, 63, 137, 183, 302, 101, 3]
Output: <start> 玉 鼠 喜 春 来 <end> [2, 126, 312, 17, 4, 26, 3]

Input:  <start> 锦 绣 花 似 锦 <end> [2, 68, 117, 8, 185, 68, 3]
Output: <start> 缤 纷 春 如 风 <end> [2, 1651, 744, 4, 140, 7, 3]

Input:  <start> 春 风 送 暖 山 河 好 <end> [2, 4, 5, 183, 60, 7, 71, 45, 3]
Output: <start> 瑞 雪 迎 春 世 纪 新 <end> [2, 92, 90, 27, 4, 36, 99, 5, 3]

Input:  <start> 百 花 争 艳 春 风 得 意 <end> [2, 48, 8, 164, 76, 4, 5, 197, 50, 3]
Output: <start> 万 马 奔 腾 喜 气 福 多 <end> [2, 6, 28, 167, 58, 17, 33, 15, 113, 3]

2. Реализация

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

В Интернете есть проект с открытым исходным кодом, который содержит набор данных на 700 000. Адрес проекта следующий:GitHub — wb14123/couplet-dataset: набор данных для куплетов, база данных на 700 000 куплетов..

Однако я не удовлетворен, потому что мне нужны куплеты Весеннего праздника, а не двустишия.

Хотя куплет содержит двустишия Праздника Весны, куплеты Праздника Весны полны народных обычаев и полны праздничного и мирного вкуса.

Так что я нашел в Интернете веб-сайт с куплетами «Весенний фестиваль».www.duiduilian.com/chunlian/, содержимое внутри хорошего качества. Итак, я написал программу-краулер для сбора данных.

2.1 Элементы анализа

Откройте URL-адрес, и в браузере нажмите F12, чтобы проанализировать веб-страницу.

2022-01-18_150928.png

Из анализа видно, что основное содержание нашего внимания заключается в<div class="content_zw"></div>между и куплет используется<p></p>пакет, верх и низсегментация.

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

Если мы хотим получить содержимое куплетов Весеннего фестиваля, нам нужно только загрузить html-код через URL-адрес, затем вынуть часть тела, а затем передать<p>Ярлыки группируются, каждая пара куплетов Праздника Весны отделяется запятыми "," и, наконец, сохраняется в файле.

Открыть для сушки.

2.2 Удалить текст

Сначала загрузите URL-адрес и удалите текст, который нам нужен.

import requests
import re

# 模拟浏览器发送http请求
response = requests.get(url)
# 设置编码方式
response.encoding='gbk'
# 获取整个网页html
html = response.text
# 根据标签分析,从html中获取正文
allText = re.findall(r'<div class="content_zw">.*?</div>', html, re.S)[0]
print(url+"\n allText:"+allText)

Стоит упомянуть, чтоreэто библиотека поддержки для регулярных выражений, указанная вышеre.findallизhtmlНайти все фигуры в тексте, похожие на<div class="content_zw">乱七八糟什么内容都行</div>Содержание. Потому что их может быть больше одной, но здесь только одна сцена, так что берите первую.[0]это то, что мы хотим.

Таким образом, мы получаем следующее:

<div class="content_zw">
<p>春来眼际,喜上眉梢</p>
<p>春光普照,福气长临</p>
<p>春和景明,物阜年丰</p>
<p>春降大地,福满人间</p>
<p>春明花艳,民富国强</p>
……
</div>

2.3 Удалить куплет

Из целевого HTML-текста выберите куплеты.

text = "<div class='content_zw'><p>春来眼际,喜上眉梢</p><p>春光普照,福气长临</p></div>"
couplets = re.findall(r'<p>(.*?)</p>',text)
print(couplets) # ['春来眼际,喜上眉梢', '春光普照,福气长临']
for couplet in couplets:
    cs = couplet.split(",")
    print("上联:",cs[0], ",下联:",cs[1])
    # 上联: 春来眼际 ,下联: 喜上眉梢 上联: 春光普照 ,下联: 福气长临

все еще используется здесьre.findall. Этот метод очень часто используется в программах-краулерах. Так называемое сканирование данных — это фактически получение полного текста, а затем отрывание интересующего вас фрагмента текста. Как рвать зависит отreС рядом правил для достижения.

re.findall(r'<p>(.*?)</p>',text)означает отtext, Выбрать<p>乱七八糟什么内容都行</p>Содержимое в скобках формы. Здесь стоит упомянуть, что только()содержимое внутри.

Например:

text = "<p>春来眼际,喜上眉梢</p>"
text_r1 = re.findall(r'<p>(.*?)</p>',text)[0]
print(text_r1) # 春来眼际,喜上眉梢
text_r2 = re.findall(r'<p>.*?</p>',text)[0]
print(text_r2) # <p>春来眼际,喜上眉梢</p>

Глядя на два приведенных выше примера, вы можете понять разницу между скобками и без них.

понятноcoupletsна самом деле массив['春来眼际,喜上眉梢', '春光普照,福气长临']. Затем снова выполните цикл по массиву,split(",")Разделить вверх и вниз. Таким образом, у вас есть двустишия Праздника Весны для верхних и нижних суставов, а затем вы можете делать все, что хотите.

2.4 Также есть пагинация

Выше только что сказал URL-адрес страницы.

Но на самом деле параллельных страниц очень много.

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

Ниже приведен анализ html-кода пейджинговой части:

2022-01-18_151941.png

Мы можем видеть из отладки F12, что пейджинговая часть такая же, как куплеты Весеннего фестиваля, и она такжеdiv.content_zwВнутри его общая этикетка<div id="pages"></div>завернутый.

<div id="pages">
    <a class="a1" href="/chunlian/4zi.html">上一页</a> 
    <span>1</span> 
    <a href="/chunlian/4zi_2.html">2</a> 
    <a href="/chunlian/4zi_3.html">3</a> 
    ……
    <a href="/chunlian/4zi_8.html">8</a> 
    <a class="a1" href="/chunlian/4zi_2.html">下一页</a>
</div>

вaвнутри этикеткиhrefэто относительный путьurlПодключайтесь, попробуем получить.

# 获取分页相关的网页html
pages = re.findall(r'<div id="pages">.*?</div>', allText, re.S)[0]
page_list = re.findall(r'href="/chunlian/(.*?)">(.*?)<',pages)
page_urls = []
for page in page_list:
    if page[1] != '下一页':
        page_url="https://www.duiduilian.com/chunlian/%s" % page[0]
        page_urls.append(page_url)
# page_urls 就是所有链接

Я считаю, что с помощью предыдущих инструкций вы уже можете понять большую часть кода здесь. это и получитьpКуплеты в этикетке очень похожи, разница в том, что есть2Кусок(). Давайте напечатаем соответствиеpage_list:

page_list: [('4zi.html', '上一页'), ('4zi_2.html', '2'), ('4zi_3.html', '3')
, ('4zi_4.html', '4'), ('4zi_5.html', '5'), ('4zi_6.html', '6')
, ('4zi_7.html', '7'), ('4zi_8.html', '8'), ('4zi_2.html', '下一页')]

оригинальный,re.findall(r'href="/chunlian/(.*?)">(.*?)<',pages)Это значит, что нам нужно занять 2 места, которые……/chunlian/(这个位置1)">(这个位置2)<…….

Помимо кнопки «Далее», другие<a>В ссылке точно полный адрес страниц 1-8, так что мы можем получить все это.

2.5 Весь код

Ну и пагинация тоже сделана, значит все ссылки есть, и как оторвать куплетное предложение Праздник Весны по каждой ссылке тоже есть.Далее весь код.

import requests
import re 

def getContent(url):
    response = requests.get(url)
    response.encoding='gbk'
    html = response.text
    allText = re.findall(r'<div class="content_zw">.*?</div>', html, re.S)[0]
    return allText

def getPageUrl(allText):
    pages = re.findall(r'<div id="pages">.*?</div>', allText, re.S)[0]
    page_list = re.findall(r'href="/chunlian/(.*?)">(.*?)<',pages)
    page_urls = []
    for page in page_list:
        if page[1] != '下一页':
            page_url="https://www.duiduilian.com/chunlian/%s" % page[0]
            print("page_url:",page_url)
            page_urls.append(page_url)
    return page_urls

def do(url, file_name):
    c_text = getContent(url)
    pages = getPageUrl(c_text)
    f = open(file_name,'w')
    for page_url in pages:
        page_text = getContent(page_url)
        page_couplets = re.findall(r'<p>(.*?)</p>',page_text)
        str = '\n'.join(page_couplets)+'\n'
        f.write(str)
    f.close() 

url = 'https://www.duiduilian.com/chunlian/4zi.html'
file_name = 'blog4.txt'
do(url, file_name)

Я намеренно опустил комментарии, потому что хотел сказать, что эта функция на самом деле состоит всего из 30 строк кода.

Наконец, он сохраняет полученные данные в файл с именем blog4.txt.

2022-01-18_163609.png

Это 4-символьный куплет Праздника Весны, а также есть 5-символьные, 6-символьные и 7-символьные.Вы можете следовать тому же методу.

3. Идеалы и реальность

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

Поев, я скажу вам, что реализация вышеуказанных 30 строк кода на самом деле является идеальной ситуацией, а реальность невозможна.

На самом деле есть много исключений.

Например, следующий текст куплетов Праздника Весны<p>Есть вещи, которые мы хотим, и вещи, которые мы не хотим видеть на лейблах.

2022-01-18_164516.png

Посмотрите еще раз, в куплетах Праздника Весны нет текста.<p>Этикетка, то можно придумать способ.

2022-01-18_165013.png

Посмотрите еще раз на следующее: когда страниц слишком много, появляется многоточие, ссылки некоторых номеров страниц неполные, а некоторые данные не могут быть получены.2022-01-18_164806.png

Наконец, посмотрите на следующее: нумерация страниц имеет форму списка, и вы не можете адаптировать ее с помощью исходного метода.

2022-01-18_164651.png

Да, разница между туториалами и настоящим боем все же есть.

Учебник, чем чище, тем лучше, кратчайшее расстояние, чтобы сказать точку знаний, тем меньше помех, тем лучше.

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

Эта моя статья — учебник по некоторым односторонним знаниям, основная цель — сделать научно-популярную работу. Недостаточно, но и надеюсь, что все Haihan.

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