- Соси кошек вместе с кодом! Эта статья участвует【Эссе "Мяу Звезды"】.
Наггетс недавно запустили "«Сосущие кошки» с кодом", запустивший две душевные пытки:
- у тебя есть кот?
- Вы завидуете людям, у которых есть кошки?
Мой ответ: у меня нет кошек, и я не завидую людям, у которых есть кошки. Занятие требует использования кодов для привлечения кошек.Посмотрев это занятие, я обнаружил, что есть довольно много друзей, которые интересуются кошками.Некоторые друзья из группы всегда показывают мне кошек, что вызывает у меня любопытство к кошкам.
Если вы хотите сосать кошку, вы должны сначала купить кошачью ручку? Если вы хотите купить кошку, вы должны хотя бы сначала понять кошек, верно?Как человек, который мало что знает о кошках, сегодня я воспользуюсь этим заданием, чтобы познакомиться со всеми видами домашних кошек.
Здесь я нашел сайт, посвященный торговле кошками — Maomao Trading Network:www.maomijiaoyi.com/
В разделе «Породы кошек» перечислены различные типы домашних кошек:Мы можем собирать данные и узнавать о характеристиках различных домашних кошек.
В итоге эта статья имеет следующие результаты:
Сбор данных
Сначала мы сканируем список ссылок, по которым может сканироваться домашняя страница:
from lxml import etree
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
}
url_base = "http://www.maomijiaoyi.com"
session = requests.Session()
# 访问猫咪品种入口页,获取各品种详情页的链接
url = url_base+"/index.php?/pinzhongdaquan_5.html"
res = session.get(url, headers=headers)
html = etree.HTML(res.text)
main_data = []
for a_tag in html.xpath("//div[@class='pinzhong_left']/a"):
url = url_base+a_tag.xpath("./@href")[0]
pet_name, pet_price = None, None
pet_name_tag = a_tag.xpath("./div[@class='pet_name']/text()")
if pet_name_tag:
pet_name = pet_name_tag[0].strip()
pet_price_tag = a_tag.xpath("./div[@class='pet_price']/span/text()")
if pet_price_tag:
pet_price = pet_price_tag[0].strip()
print(pet_name, pet_price, url)
main_data.append((pet_name, pet_price, url))
Результат печати следующий:
Если я хочу узнать больше о кошках, мне нужно щелкнуть страницу сведений, чтобы увидеть подробные свойства:
Разберите данные этих трех частей отдельно и протестируйте разбор первой ссылки:
pet_name, pet_price, url = main_data[0]
res = session.get(url, headers=headers)
html = etree.HTML(res.text)
row = {}
# 解析基本属性
for text in html.xpath("//div[@class='details']//text()"):
text = text.strip()
if not text:
continue
if text.endswith(":"):
key = text[:-1]
else:
row[key] = text
row["参考价格"] = pet_price
# 解析外观属性
for shuxing in html.xpath("//div[@class='shuxing']/div"):
name, v = shuxing.xpath("./div/text()")
row[name.strip()] = v.strip()
row["链接"] = url
# 解析详细说明
titles = html.xpath(
"//div[@class='content']/div[@class='property_title']/div/text()")
property_tags = html.xpath(
"//div[@class='content']/div[@class='property_list']/div")
for title, property_tag in zip(titles, property_tags):
p_texts = []
for p_tag in property_tag.xpath(".//p|.//div"):
p_text = "".join([t.strip()
for t in p_tag.xpath(".//text()") if t.strip()])
if p_text:
p_texts.append(p_text)
text = "\n".join(p_texts)
row[title] = text
row
Видно, что данные первых двух частей разбираются очень плавно:
Для третьей части данных также успешно парсится:
Помимо информации текстового описания, нам также необходимо сохранить изображение. Следующий код анализирует URL-адрес изображения и загружает его:
img_urls = [
url_base+url for url in html.xpath("//div[@class='big_img']/img/@src") if url]
row["图片地址"] = img_urls
for i, img_url in enumerate(img_urls, 1):
with requests.get(img_url) as res:
imgbytes = res.content
with open(f"imgs/{pet_name}{i}.jpg","wb") as f:
f.write(imgbytes)
Вы можете видеть, что несколько изображений были успешно загружены:
Затем мы можем организовать код веб-сайта, сохранить текстовые данные в Excel и сохранить картинку в файл:
import pandas as pd
from lxml import etree
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
}
url_base = "http://www.maomijiaoyi.com"
session = requests.Session()
# 访问猫咪品种入口页,获取各品种详情页的链接
url = url_base+"/index.php?/pinzhongdaquan_5.html"
res = session.get(url, headers=headers)
html = etree.HTML(res.text)
main_data = []
for a_tag in html.xpath("//div[@class='pinzhong_left']/a"):
url = url_base+a_tag.xpath("./@href")[0]
pet_name, pet_price = None, None
pet_name_tag = a_tag.xpath("./div[@class='pet_name']/text()")
if pet_name_tag:
pet_name = pet_name_tag[0].strip()
pet_price_tag = a_tag.xpath("./div[@class='pet_price']/span/text()")
if pet_price_tag:
pet_price = pet_price_tag[0].strip()
main_data.append((pet_name, pet_price, url))
data = []
for pet_name, pet_price, url in main_data:
res = session.get(url, headers=headers)
html = etree.HTML(res.text)
row = {}
# 解析基本属性
for text in html.xpath("//div[@class='details']//text()"):
text = text.strip()
if not text:
continue
if text.endswith(":"):
key = text[:-1]
else:
row[key] = text
row["参考价格"] = pet_price
# 解析外观属性
for shuxing in html.xpath("//div[@class='shuxing']/div"):
name, v = shuxing.xpath("./div/text()")
row[name.strip()] = v.strip()
row["链接"] = url
# 解析详细说明
titles = html.xpath(
"//div[@class='content']/div[@class='property_title']/div/text()")
property_tags = html.xpath(
"//div[@class='content']/div[@class='property_list']/div")
for title, property_tag in zip(titles, property_tags):
p_texts = []
for p_tag in property_tag.xpath(".//p|.//div"):
p_text = "".join([t.strip()
for t in p_tag.xpath(".//text()") if t.strip()])
if p_text:
p_texts.append(p_text)
text = "\n".join(p_texts)
row[title] = text
img_urls = [
url_base+url for url in html.xpath("//div[@class='big_img']/img/@src") if url]
row["图片地址"] = img_urls
data.append(row)
for i, img_url in enumerate(img_urls, 1):
with requests.get(img_url) as res:
imgbytes = res.content
with open(f"imgs/{pet_name}{i}.jpg", "wb") as f:
f.write(imgbytes)
df = pd.DataFrame(data)
df.to_excel("猫咪.xlsx", index=False)
Первые несколько столбцов результатов сканирования выглядят следующим образом:
Скачал картинки разных кошек:
С помощью приведенных выше данных Excel мы можем анализировать и обрабатывать:
анализ данных
Сначала прочитайте данные в Excel:
import pandas as pd
df = pd.read_excel("猫咪.xlsx")
Данные наблюдений показали, что многие домашние кошки имеют несколько псевдонимов. Мы можем построить диаграмму отношений, чтобы показать псевдонимы, соответствующие каждой кошке:
from pyecharts import options as opts
from pyecharts.charts import Graph
links = []
nodes = []
nodes.append({"name": "猫", "symbolSize": 10})
for name, alias in df[["中文学名", "别名"]].values:
nodes.append({"name": name, "symbolSize": 10})
links.append({"source": "猫", "target": name})
for dest in alias.split(","):
if name == dest:
continue
nodes.append({"name": dest, "symbolSize": 10})
links.append({"source": name, "target": dest})
c = (
Graph(init_opts=opts.InitOpts(width="800px", height="800px"))
.add("", nodes, links, repulsion=250,
linestyle_opts=opts.LineStyleOpts(width=0.5, curve=0.3, opacity=0.7))
.set_global_opts(title_opts=opts.TitleOpts(title="宠物猫的品种"))
)
c.render_notebook()
Основное имя можно просмотреть, когда указатель мыши указывает на центральную точку:
Распределение происхождения Pet Cats:
from pyecharts.charts import Bar
data = df.原产地.value_counts()
c = (
Bar()
.add_xaxis(data.index.to_list())
.add_yaxis("", data.values.tolist())
.set_global_opts(
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=15)),
title_opts=opts.TitleOpts(title="宠物猫原产地分布")
)
)
c.render_notebook()
Это можно увидеть в различных домашних животных, в основном распределенных в Соединенном Королевстве, Соединенных Штатах и Шотландии.
Затем нарисуйте древовидную диаграмму, показывающую страны, в которых распространены кошки каждой породы:
data = []
tmp = df.groupby("原产地", as_index=False).agg(
品种=("中文学名", ",".join), 品种数=("中文学名", "count"))
for src, dest in tmp.values[:, :2]:
dests = dest.split(",")
children = []
data.append({"value": len(dests), "name": src, "children": children})
for dest in dests:
children.append({"name": dest, "value": 1})
c = (
TreeMap(init_opts=opts.InitOpts(width='1280px', height='560px'))
.add("", data,
levels=[
opts.TreeMapLevelsOpts(
treemap_itemstyle_opts=opts.TreeMapItemStyleOpts(
border_color="#555", border_width=1, gap_width=1
)
),
opts.TreeMapLevelsOpts(
color_saturation=[0.3, 0.6],
treemap_itemstyle_opts=opts.TreeMapItemStyleOpts(
border_color_saturation=0.7, gap_width=5, border_width=10
),
upper_label_opts=opts.LabelOpts(
is_show=True, position='insideTopLeft', vertical_align='top'
)
),
opts.TreeMapLevelsOpts(
color_saturation=[0.3, 0.5],
treemap_itemstyle_opts=opts.TreeMapItemStyleOpts(
border_color_saturation=0.6, gap_width=1
),
),
opts.TreeMapLevelsOpts(color_saturation=[0.3, 0.5]),
])
.set_global_opts(title_opts=opts.TitleOpts(title="宠物猫原产地分布"))
)
c.render_notebook()
Тогда посмотрите на соотношение разновидностей и размеров тела:
from pyecharts.charts import Pie
c = (
Pie()
.add(
"体型",
df.体型.value_counts().reset_index().values.tolist(),
radius=["40%", "55%"],
label_opts=opts.LabelOpts(
position="outside",
formatter="{a|{a}}{abg|}\n{hr|}\n {b|{b}: }{c} {per|{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=1,
border_radius=4,
rich={
"a": {"color": "#999", "lineHeight": 22, "align": "center"},
"abg": {
"backgroundColor": "#e3e3e3",
"width": "100%",
"align": "right",
"height": 22,
"borderRadius": [4, 4, 0, 0],
},
"hr": {
"borderColor": "#aaa",
"width": "100%",
"borderWidth": 0.5,
"height": 0,
},
"b": {"fontSize": 16, "lineHeight": 33},
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="品种体型占比"),
)
)
c.render_notebook()
Только один размер кошки считается самым большим, это Рэгдолл. Ниже мы находим самых дешевых и самых дорогих кошек.В настоящее время считается, что самая низкая цена - самая дешевая порода, а самая высокая цена - самая дорогая порода:
tmp = df.参考价格.str.split("-", expand=True)
tmp.columns = ["最低价格", "最高价格"]
tmp.dropna(inplace=True)
tmp = tmp.astype("int")
cheap_cat = df.loc[tmp.index[tmp.最低价格 == tmp.最低价格.min()], "中文学名"].to_list()
costly_cat = df.loc[tmp.index[tmp.最高价格 == tmp.最高价格.max()], "中文学名"].to_list()
print("最便宜的品种有:", cheap_cat)
print("最贵的品种有:", costly_cat)
最便宜的品种有: ['加菲猫', '金渐层', '银渐层', '橘猫']
最贵的品种有: ['布偶猫', '缅因猫', '无毛猫']
Для ['всего', 'волосы', 'цвет', 'голова', 'глаза', 'уши', 'нос', 'хвост', 'грудь', 'шея', 'предшественник' в наборе данных, ' задний привод'] Все эти столбцы являются описаниями кошек, мы можем объединить их в единое целое, чтобы составить карту облака слов для кошек:
import stylecloud
from IPython.display import Image
text = ""
for row in df[['整体', '毛发', '颜色', '头部', '眼睛', '耳朵',
'鼻子', '尾巴', '胸部', '颈部', '前驱', '后驱']].values:
for v in row:
if pd.isna(v):
continue
text += v
stylecloud.gen_stylecloud(text,
collocations=False,
font_path=r'C:\Windows\Fonts\msyhbd.ttc',
icon_name='fas fa-cat',
output_name='tmp.png')
Image(filename='tmp.png')
Затем мы делаем карты облаков слов для характеристик личности и жизненных привычек.
Карта облака слов с характеристиками символов:
import jieba
import stylecloud
from IPython.display import Image
stopwords = ["主人", "它们", "毛猫", "不会", "性格特点", "猫咪"]
words = df.性格特点.astype("str").apply(jieba.lcut).explode()
words = words[words.apply(len) > 1]
words = [word for word in words if word not in stopwords]
stylecloud.gen_stylecloud(" ".join(words),
collocations=False,
font_path=r'C:\Windows\Fonts\msyhbd.ttc',
icon_name='fas fa-square',
output_name='tmp.png')
Image(filename='tmp.png')
import jieba
import stylecloud
from IPython.display import Image
stopwords = ["主人", "它们", "毛猫", "不会", "性格特点", "猫咪"]
words = df.生活习性.astype("str").apply(jieba.lcut).explode()
words = words[words.apply(len) > 1]
words = [word for word in words if word not in stopwords]
stylecloud.gen_stylecloud(" ".join(words),
collocations=False,
font_path=r'C:\Windows\Fonts\msyhbd.ttc',
icon_name='fas fa-square',
output_name='tmp.png')
Image(filename='tmp.png')
генерация кошачьего графа
После приведенного выше анализа у нас есть базовое представление о кошках, а затем мы создадим изображение каждой породы кошек.
Какую картинку мне сделать? Я тщательно все обдумал и составил ментальную карту.
Сначала сгенерируйте категорический текст:
for a, bs in df.中文学名.groupby(df.体型):
print(a)
for b in bs.values:
print(f"\t{b}")
中型
加菲猫
金渐层
英短蓝猫
英短蓝白
英国短毛猫
美国短毛猫
苏格兰折耳猫
银渐层
异国短毛猫
孟买猫
暹罗猫
孟加拉豹猫
大型
布偶猫
小型
缅因猫
金吉拉猫
无毛猫
高地折耳猫
曼基康矮脚猫
波斯猫
橘猫
阿比西尼亚猫
德文卷毛猫
На данный момент я вставляю его в карту разума, а затем отредактируйте его часто на некоторое время, чтобы получить: