不知大家会不会有这样的困惑
每发一款新产品之前,领导都会问你别人是怎么做的
每到新的一个月,领导就需要知道同业的情况和对比
而人为去跟踪不仅耗时耗力
且无法跟踪完全
今天来讲一个利用网络爬虫来节省时间的方法~~
代码感谢陈朝棕大佬投稿
网络数据采集基础
这部分的内容其实之前有写过,手把手教你学python第五课:各种渠道获取数据,快速学会windpy和网络爬虫,当时说要给大家找几个例子,一个例子是如何用大数据技术搭建政策分析框架?,讲了怎么应用爬虫来抓取政府及YM网站的数据并进行归纳总结的,而第二个例子就是本文的例子拉~~
首先来复习下那节课的内容:
网络数据采集指通过程序化方式批量解析保存指定网页中所需数据,相对完整的采集程序包含了数据采集、数据清洗、数据入库、任务调度等。
作为初步入门的介绍性资料,本Notes仅涉及数据采集和数据清洗的内容,通过一些案例分别展示常规数据采集和需要模拟浏览器操作的数据采集。代码部分采用Python实现。
工具准备
Python环境:推荐直接安装Anaconda
官方:https://www.anaconda.com/products/individual
清华镜像:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive
本Notes在Anaconda的基础上需要额外安装两个包:httpx、pyppeteer, 可使用 pip install 进行安装。httpx用于常规数据采集,与requests的用法类似;pyppeteer主要用于部分加载过程比较复杂的页面,通过模拟浏览器操作进行采集,与selenium的用法类似。
可能用到的Python程序包:
httpx:发起网络请求;官方文档:https://www.python-httpx.org/
pyppeteer:模拟浏览器操作;官方文档:
https://pyppeteer.github.io/pyppeteer/
lxml:解析获取的html页面,通过xpath披露解析数据;官方文档:
https://lxml.de/parsing.html
pandas:整理保存采集到的数据;官方文档:
https://pandas.pydata.org/pandas-docs/stable/
其他工具:chrome(开发者工具),通过Network界面跟踪采集数据的真实地址和请求参数。
其他知识点:除了Python外,网络数据采集还需要对网页的文档格式有一定了解:
关于html简介,可参考:
https://www.w3school.com.cn/html/html_jianjie.asp
关于xpath解析数据,可参考:
https://www.w3school.com.cn/xpath/index.asp
# 导入所需程序包
import httpx
import pyppeteer
from lxml import etree
import pandas as pd
案例一:采集HTML页面的数据
采集目标:中国理财网-数据分析-理财报告:https://www.chinawealth.com.cn/zzlc/sjfx/lcbg/list.shtml
打开chrome开发者工具并切换到Network页,输入采集目标地址后,跟踪Network页面的变化,寻找并确认数据信息所在的真实地址,以及完成请求需要的Request Headers信息。
真实数据地址没有变化:https://www.chinawealth.com.cn/zzlc/sjfx/lcbg/list.shtml
请求方式:get
# 初始化 httpx
spider = httpx.Client(
# 设置通用的请求头
headers= {
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"DNT": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36",
}
)
# 请求目标地址获取网页
page = spider.get("https://www.chinawealth.com.cn/zzlc/sjfx/lcbg/list.shtml")
# 将网页字符串转为HTML,便于通过xpath提取数据
page_html = etree.HTML(page.text)
# 整理网页数据内容到dataframe
page_data = pd.DataFrame(
{
"标题": page_html.xpath("""//ul[@class="news_list"]//h2[@class="news_name"]/a/@href"""),
"详情链接": page_html.xpath("""//ul[@class="news_list"]//h2[@class="news_name"]/a/@title"""),
"来源": ["".join(e.xpath("./text()")).strip() for e in page_html.xpath("""//ul[@class="news_list"]//div[@class="news_other"]""")],
"发布日期": [d.strip() for d in page_html.xpath("""//ul[@class="news_list"]//span[@class="news_date"]/text()""")],
}
)
案例二:采集json数据
采集目标:中国理财网-理财产品:https://www.chinawealth.com.cn/zzlc/jsp/lccp.jsp
打开chrome开发者工具并切换到Network页,输入采集目标地址后,跟踪Network页面的变化,寻找并确认数据信息所在的真实地址,以及完成请求需要的Request Headers信息。
真实数据地址:https://www.chinawealth.com.cn/LcSolrSearch.go
请求方式:post
请求参数(作为示例,不尝试理解参数具体含义):cpjglb: cpyzms: cptzxz: cpfxdj: cpqx: mjbz: cpzt: 02 mjfsdm: 01,NA cpdjbm: cpmc: cpfxjg: yjbjjzStart: yjbjjzEnd: areacode: pagenum: 1 orderby:
# 初始化 httpx
spider = httpx.Client(
# 设置通用的请求头
headers= {
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"DNT": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36",
}
)
# 构造请求参数字典
data = dict(
cpjglb="",
cpyzms="",
cptzxz="",
cpfxdj="",
cpqx="",
mjbz="",
cpzt="02",
mjfsdm="01,NA",
cpdjbm="",
cpmc="",
cpfxjg="",
yjbjjzStart="",
yjbjjzEnd="",
areacode="",
pagenum="1",
orderby="",
)
# 请求目标地址获取json字符串
page = spider.post("https://www.chinawealth.com.cn/LcSolrSearch.go", data=data)
# 转换json字符串为字典
page_json = page.json()
# 将json字典转换为dataframe,丢弃不需要的数据列
page_data = pd.json_normalize(page_json, record_path="List").drop(columns=["copy"])
page_data.to_excel('licai.xlsx')
当然如果需要进行后一步的分析的话可以继续用pandas的画图功能,如:
page_data["fxjgms"].value_counts().plot.pie(autopct='%1.2f%%',figsize=(5, 5))
内容涵盖了风险等级、开放类型、期限、募集开始结束日期、实际天数、业绩基准等多重信息(如有)。
案例三:通过模拟浏览器操作采集数据
采集目标:中国人民银行-调查统计-数据解读:http://www.pbc.gov.cn/diaochatongjisi/116219/116225/index.html
难点:pyppeteer使用了Python的异步编程,使用中需结合async/await关键字,类似本案例的常规使用中并不复杂。pyppeteer提供了数据解析的能力,本案例仍然结合lxml进行数据解析。
# 初始化pyppeteer,用于操作浏览器,修改headless参数为True可以隐藏浏览器界面
browser = await pyppeteer.launch({"headless": False, "dumpio": True })
# 创建新页面,并允许js脚本运行
page = await browser.newPage()
await page.setJavaScriptEnabled(enabled=True)
# 进入采集目标页面
await page.goto("http://www.pbc.gov.cn/diaochatongjisi/116219/116225/index.html")
# 等待页面加载完成
await page.waitForXPath("//input[@totalpage]/@totalpage")
# 转换页面内容字符串为HTML
page_content = await page.content()
page_html = etree.HTML(page_content)
# 整理网页数据内容到dataframe
page_data = pd.DataFrame(
{
"标题": page_html.xpath("""//div[@opentype="page"]//tbody/tr//a[contains(@href,"diaochatongjisi")]/@title"""),
"发布日期": page_html.xpath("""//div[@opentype="page"]//tbody/tr//a[contains(@href,"diaochatongjisi")]/../../span[@class="hui12"]/text()"""),
"详情链接": page_html.xpath("""//div[@opentype="page"]//tbody/tr//a[contains(@href,"diaochatongjisi")]/@href"""),
}
)
# 关闭模拟浏览器
await browser.close()
以上只是数据的采集工作,当大家采集到相应的数据之后,如何去进行相应的分析和处理,才是理解数据最重要的一步,我平时常用的就是pandas的画图功能,如果有条件的使用Tableau或者JS来画图的就更好了,具体的画图和分析代码这里也有讲过手把手教你学python第三课:数据分析,学会使用pandas大杀器
手把手教你学python系列,其实更新的频率很慢,也是为了让大家能每一个都亲自动手尝试和消化了再出下一个(当然还有个原因是我懒),希望大家都能坚持下去哦~~~