2018.11.22

爬虫要求:
目标 url:http://gs.amac.org.cn/amac-infodisc/res/pof/fund/index.html
抓取信息:每条基金的 基金名称 私募基金管理人名称 托管人名称 成立时间 备案时间
基金具体url。
即下图信息+url 链接

一、环境
安装好 Anaconda(Python 版本为 3.6)即可,较简单,教程较多,如:https://www.jianshu.com/p/62f155eb6ac5
不过我建议大家可以勾选“Add Anaconda to my PATH environment variable.”(“添加Anaconda至我的环境变量。”),自行决定,我勾选了,省的环境变量出错。

二、分析

打开目标网页,右键选择查看源代码,发现需要爬取的信息在源代码中没有显示,比如‘嘉兴全意投资合伙企业’,在源代码中搜索不到。并且当更换页数时,网页 url 并没有改变。此种情况,应该是网页的内容是由 JavaScript 渲染而成,请求 url 返回的是一些 JavaScript 代码。怎么办?两种思路:

  • 运用 Selenium 库,所见即所爬!(网页上看到什么就能爬取什么,但是目前淘宝等网页有针对 Selenium 进行的反爬,但是也有相应的绕过反爬的方法,此处不细说)但是 Selenium 致命缺点是,效率!因为是模拟出浏览器的实际操作,所以在爬取的效率上比较低,而且占用电脑的操作。
  • 分析接口参数,找到网页请求的实际 url,然后再进行请求。

三、 实战
方法 1:
占坑。
填坑,贴下代码,含注释,写的比较糙,懒得改了。若是未安装 Selenium 模块,需要在 anaconda 控制台输入conda install selenium 来安装该模块,同时,我用的是 Chrome 浏览器,并且还要安装 Chrome Driver。

from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from lxml import etree
import time
import openpyxlbrowser = webdriver.Chrome()  # 创建一个谷歌浏览器对象
browser.get('http://gs.amac.org.cn/amac-infodisc/res/pof/fund/index.html')  # 打开网址
wait = WebDriverWait(browser,10)  # 设置最长等待时间 10s
option_100=browser.find_element_by_xpath('//*[@id="fundlist_length"]/label/select') # 找到每页显示100 条 的位置
Select(option_100).select_by_value('100')  # 选择每页显示 100 条
wait.until(EC.text_to_be_present_in_element((By.XPATH,'//*[@id="fundlist"]/tbody/tr[100]/td[1]'),'100')) # 等待第100 个信息加载出来
button = wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[6]/div[3]/div/button[@style="color: rgb(85, 85, 85);"]'))) # 等待 关闭 按钮加载出来
button.click()  # 点击关闭按钮
input = wait.until(EC.presence_of_element_located((By.XPATH,'//*[@id="goInput"]'))) # 等待 选择页数 输入框加载出来
lis = [] # 创建一个列表,用来存放字典
for page in range(1,100):  # 爬取页数 范围设置input.clear() # 清除页数输入框内内容input.send_keys(str(page)) # 向框内填写 pagebutton = browser.find_element_by_xpath('//*[@id="fundlist_paginate"]/button') # 找到 转到 按钮button.click() # 点击按钮wait.until(EC.text_to_be_present_in_element((By.XPATH,'//*[@id="fundlist_paginate"]/span//a[@active="true"]'),str(page))) # 等待该页高亮显示出来text = browser.page_source  # 获取该页 源码selector = etree.HTML(text) # 创建 XPATH 选择器for i in range(1,101):  # 爬取该页的条数的范围dic = {} # 创建一个字典,存放信息num = selector.xpath('//*[@id="fundlist"]/tbody/tr[%d]/td[1]/text()'%i)[0]  # 编号name = selector.xpath('//*[@id="fundlist"]/tbody/tr[%d]/td[2]/a/text()'%i)[0]  # 名称name2 = selector.xpath('//*[@id="fundlist"]/tbody/tr[%d]/td[3]/a/text()'%i)[0] # 私募基金管理人名称manager = selector.xpath('//*[@id="fundlist"]/tbody/tr[%d]/td[4]//text()'%i) # 托管人名称if not manager:manager = ''else:manager = manager[0]time1 = selector.xpath('//*[@id="fundlist"]/tbody/tr[%d]/td[5]/text()'%i) # 成立时间if not time1:time1 = ''else:time1 = time1[0]time2 = selector.xpath('//*[@id="fundlist"]/tbody/tr[%d]/td[6]/text()'%i) # 备案时间if not time2:time2 = ''else:time2 = time2[0]# 将信息存入字典中dic['num']=int(num)+(page-1)*100dic['name']=namedic['name2']=name2dic['manager']=managerdic['time1']=time1dic['time2']=time2lis.append(dic)  # 将字典存入列表中
# print(lis)
browser.close()  # 关闭浏览器
# '''
excel = openpyxl.Workbook() # 创建 excel
sheet = excel.active  # 找到当前页
length = len(lis) # 列表长度,即共抓取多少条信息
# 设置表头
sheet['A1'] = '编号'
sheet['B1'] = '基金名称'
sheet['C1'] = '私募基金管理人名称'
sheet['D1'] = '托管人名称'
sheet['E1'] = '成立时间'
sheet['F1'] = '备案时间'
# 将爬取到的信息存放到 excel 中
for i in range(2,length+2):sheet['A%d'%i] = lis[i-2]['num']sheet['B%d'%i] = lis[i-2]['name']sheet['C%d'%i] = lis[i-2]['name2']sheet['D%d'%i] = lis[i-2]['manager']sheet['E%d'%i] = lis[i-2]['time1']sheet['F%d'%i] = lis[i-2]['time2']
print('Done')
excel.save('result.xlsx') # 保存文件

方法2:
打开目标 url,按下 F12进入开发者模式,选择 Network,选择 XHR,
然后点击下一页,可以看到 XHR 下面会出现新的返回,点击 Name 下的数据,如图

对该返回结果的信息分析在右侧,我们对他的 Headers 依次分析:
Request URL:该数据的实际请求 URL,可以看出 URL 中带参数rand,page,size,刚好和我们的实际网页上的信息符合(第一页,每页显示20条信息,rand 为随机数,为了防止浏览器读取缓存而不改变页面)。
Request Method:该数据的请求方法,为 Post,我们待会构造的请求 URL 方法需要与该方法保持一致。
Status Code:状态码,为 200 表示成功,服务器已成功处理了请求。
Request Headers:请求头,用来说明服务器要使用的附加信息。我们构造的爬虫的请求头可以与该请求头保持一致。
X-Requested-With:XMLHttpRequest,请求头中的信息,该信息表明次请求是 Ajax 请求。
Query String Parameters:URL 中所携带的提交的参数,可以看到与 Request URL 是对应的。我们可以构造一个字典,然后使用 urlencode 方法将这些参数写到 URL 中。
Request Payload:ajax 中所 post 的参数,该示例中为空字典,若是有相应的参数,我们可以构造对应的字典,然后转换成 json 格式的数据,再用 post 方法提交。

分析完 Headers,我们再来分析该请求所返回的结果,点击 Headers 右边的 Preview(浏览器帮我们对json格式做了解析),

可以看到,返回的是一个 Json 格式数据,包含了 content,size,totalPages 等信息,我们所需要的信息应该是在 content 中,我们再层层点开,如下:

发现 content 中包含了 20 条信息,正是页面上所显示的20条信息,点击第一条具体分析下,发现每条信息又包含了 建立日期(时间戳格式,需自己转换成日期格式,可用 time 库或者 datetime 库),基金名称…工作状态等,这些信息正是我们所想要爬取的信息。

分析完毕,我们来构造函数去请求该 url,代码如下:

from urllib.parse import urlencode
import requests
import json
import datetime
base_url = 'http://gs.amac.org.cn/amac-infodisc/api/pof/fund?'        # 请求 url 所携带参数的前面部分
fund_base_url = 'http://gs.amac.org.cn/amac-infodisc/res/pof/fund/'   # 基金 url 前面的部分
lis_json = []                                                              # 存放 json 数据headers = {                                                      # 请求头'Accept': 'application/json, text/javascript, */*; q=0.01','Accept-Encoding': 'gzip, deflate','Accept-Language': 'zh-CN,zh;q=0.9','Cache-Control':'max-age=0','Connection': 'keep-alive','Content-Length': '2','Content-Type': 'application/json','Host': 'gs.amac.org.cn','Origin': 'http://gs.amac.org.cn','Referer': 'http://gs.amac.org.cn/amac-infodisc/res/pof/fund/index.html','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','X-Requested-With': 'XMLHttpRequest'
}def get_page(page):'''爬取第xx页信息'''# url 携带参数,设置了每页显示 100 条信息params = {                                                  'rand': 0.3248183083707361,'page': page,'size': 100,}url = base_url + urlencode(params)try:r = requests.post(url,headers=headers,data=json.dumps({}))      # post 方法,将 Request Payload 的信息转换成 json 格式然后提交if r.status_code == 200:return r.json()except requests.ConnectionError as e:print('Error',e.args)def parse_page(r_json):if r_json:items = r_json.get('content')for item in items:info = {}info['基金名称'] = item.get('fundName')info['私募基金管理人名称'] = item.get('managerName')info['托管人名称'] = item.get('mandatorName')establishDate = item.get('establishDate')info['成立时间'] = str(datetime.datetime.fromtimestamp(establishDate/1000).date()) if establishDate else ''       # 成立时间有可能为空,防止这种情况而报错putOnRecordDate = item.get('putOnRecordDate')info['备案时间'] = str(datetime.datetime.fromtimestamp(putOnRecordDate/1000).date()) if putOnRecordDate else ''info['基金链接'] = fund_base_url + item.get('url')yield infodef write_to_json(lis):with open('info.json','w',encoding='utf-8') as f:json.dump({'info':lis},f,ensure_ascii=False)def main():for page in range(1,100):r_json = get_page(page)results = parse_page(r_json)for result in results:lis_json.append(result)write_to_json(lis_json)if __name__ == '__main__':main()

当然,Selenium比较慢,分析Ajxa 接口参数比Selenium快,但是需要花时间在接口参数的分析上(带加密参数时更费事),下期介绍更快的方法:Scrapy 框架!https://blog.csdn.net/luckycdy/article/details/84396587

运用 Python 爬取私募基金信息_request相关推荐

  1. 运用 Python 爬取私募基金信息_Scrapy

    2018.11.23 上一篇采用 Selenium 和 Ajax 参数分析两种方法来爬取了基金信息.链接: https://blog.csdn.net/luckycdy/article/details ...

  2. python爬取机票信息

    python爬取机票信息 飞机和高铁列车不同,在同样的航线中有着不同的票价,借此我们希望获取尽量多的机票信息来分析机票的变化规律. 首先我们选取京东机票为爬取对象http://jipiao.jd.co ...

  3. Python 爬取网页信息并保存到本地爬虫爬取网页第一步【简单易懂,注释超级全,代码可以直接运行】

    Python 爬取网页信息并保存到本地[简单易懂,代码可以直接运行] 功能:给出一个关键词,根据关键词爬取程序,这是爬虫爬取网页的第一步 步骤: 1.确定url 2.确定请求头 3.发送请求 4.写入 ...

  4. python爬取控制台信息_python爬虫实战之爬取智联职位信息和博客文章信息

    1.python爬取招聘信息 简单爬取智联招聘职位信息 # !/usr/bin/env python # -*-coding:utf-8-*- """ @Author  ...

  5. Python爬取售房信息并保存至CSV文件

    Python爬取售房信息并保存至CSV文件 在上一篇文章: Python爬取租房信息并保存至Excel文件,介绍了如何使用Python爬取租房信息并保存至Excel文件,在本案例中则是使用Python ...

  6. python爬取网页信息

    最近在学习python,发现通过python爬取网页信息确实方便,以前用C++写了个简单的爬虫,爬取指定网页的信息,代码随便一写都几百行,而要用python完成相同的工作,代码量相当少.前几天看到了一 ...

  7. python爬取电影信息并插入至MySQL数据库

    在上篇博文中,博主使用python爬取了豆瓣电影的影片信息,接下来,博主考虑到在之前做的JavaWeb电影院项目中需要向数据库中一个个的插入影片数据,十分的繁琐,那么在使用了python爬虫后,这个操 ...

  8. python爬取招聘信息_python 爬取boss直聘招聘信息实现

    原标题:python 爬取boss直聘招聘信息实现 1.一些公共方法的准备 获取数据库链接: importpymysql ''' 遇到不懂的问题?Python学习交流群:821460695满足你的需求 ...

  9. 使用python爬取天气信息(包括历史天气数据)

    使用Python爬虫获取城市天气信息(包括历史天气数据) 使用python爬取历史天气数据 文章目录 使用Python爬虫获取城市天气信息(包括历史天气数据) 一.准备工作 二.完整代码 更新 一.准 ...

最新文章

  1. python中where函数_如何在python中基于Where函数获取两列值
  2. 总结调试过程中怎么去抓log
  3. iptables的增删改查
  4. plpythonu_postgresql plpythonu例子
  5. win10-PC端无法输入中文
  6. MySQL笔记-centos7安装MySQL5.7.25(glibc版)
  7. cfd软件对电脑配置要求_这种网格划分策略,让洁净和空调CFD实施周期压缩至0.3倍...
  8. ffmpeg系列-编译
  9. 会看源码,你将比98.3%的人更容易拿到百度、阿里、腾讯、字节跳动等大公司的高薪Offer!请看这几个公众号!...
  10. 我的最爱Lambda演算——开篇
  11. 香港推广“绿色年宵” 呼吁商贩和市民惜物减废
  12. 计算机电源线税务编码,电力电子元器件税收分类编码
  13. 常用UCI数据集链接,mark
  14. Linux CentOS 重置root密码
  15. aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  16. 计时+事件倒计时网页源码分享
  17. Android 仿京东淘宝 商品详情页 商品图片效果
  18. User Agent List
  19. 怎么在计算机找到打印机驱动,教你电脑打印机驱动怎么安装
  20. 安徽万燕公司创始人安徽现代…

热门文章

  1. android华为指纹识别开发,华为正在研发“全屏指纹识别+屏下摄像头”共存机型...
  2. 同源政策(same-origin policy)
  3. 【个人经验之谈】计算机相关的就业、培训等问题解疑答惑
  4. useradd命令-c -u -G -s -d -m多个参数组合例子
  5. 下载eclipse出现a java_打开Eclipse弹出“No java virtual machine was found...的解决方法
  6. 成为自由开发者的第100天,来一波拼团活动!
  7. 闪念碎片-自动续费服务协议
  8. canvas动态绘制折线图
  9. B/S C/S 三层体系结构
  10. 结构体数组赋值的问题