【问题解决】关于爬虫被封的处理方法(同花顺数据获取问题)

37 篇文章 0 订阅
21 篇文章 6 订阅

最近试图从财经网站上积累数据,选中了同花顺财经的数据中心的数据。

插一句话,个人认为同花顺可能是目前财经领域掌握着最先进的机器学习技巧与人工智能算法的网站了。我自己最近也在做金融领域的问答与对话系统,偶然发现了同花顺i问财https://www.iwencai.com/这个网站,这种智能化的金融问答以及其叙述性的策略回测系统全网恐怕只此一家,确实是让人感到很惊艳。

言归正传,掌握了如此技术的同花顺对付几个爬虫可不是收到擒来。我试图去爬取http://data.10jqka.com.cn/funds/ggzjl/上资金流动的数据,然而无论我用什么办法,我都只能获取到前五页的数据。下面我说明一下我的操作历程:

  1. 首先自然是常规的requests.Session()模块的方法,伪装User-Agent,先定位同花顺,再进入数据中心获取数据。结果甚至连访问都无法做到,后来我尝试复制了一段真实浏览器访问的Cookie加入到session.headers中终于可以实现数据获取;
  2. 然而接下来就是无穷无尽了只能获取到前五页的数据的问题了。我尝试了爬取每页伪装一个不同IP(失败,仍然只能五页);两次访问之间设置一个60~120秒的间隔(稍有起效,但是仍然会被拒绝访问);最后我甚至猜想会不会是同花顺默认设置如果访问了前五页就不允许访问接下来的页面,于是我尝试用一个随机的顺序去访问这总共71页,结果如你所料——并没有什么P用,访问了五页后照样拒绝访问;
  3. 我最后总结下来原因应该是出在Cookie上,可是我又无法做到每次访问换一个新的Cookie,虽然继续增加访问之间的间隔时间是有效果的,但是都间隔2分钟访问一次我还不如自己手动复制页面算了;
  4. 这时候我忽然想到了selenium。以前我觉得selenium能做到的事情,我普通爬虫照样能做到,而且selenium需要实际启动浏览器,刷新页面实在是很低效的做法,同样的爬虫我用requests库能爬100页而selenium可能只能爬到30页,因此我一度觉得selenium是一个很鸡肋的爬虫手段。但是现在不同了,requests.Session()模块在同花顺面前成了纸老虎,中看不中用了,于是我重启selenium来进行爬虫;
  5. 事实上在selenium只生成一个webdriver对象的情况下仍然会被同花顺限制在五页之类的访问次数,可是如果我每访问一次都重建一个新的webdriver对象则可以避免这种情况;

不多说,直接上代码↓↓↓

Tips:笔者是使用的Firefox浏览器,因此selenium是基于Firefox的,其他不同浏览器可以把代码中的Firefox改为Chrome之类的应该就可以了。另外请自行在该py文件所在的目录下新建一个用今日日期命名的文件夹(如2019-01-27)。

# -*- coding:UTF-8 -*- 

import os
import re
import json
import time
import numpy 
import pandas
import random
import requests

from bs4 import BeautifulSoup
from selenium import webdriver

"""
	作者:囚生CY
	平台:CSDN
	时间:2019/01/27
	转载请注明原作者
	创作不易,仅供分享
"""

class StraightFlush():
	def __init__(self,
		userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0",
		cookie="v=AigMPjtB4I7PKMwKRvAplY1u-Rc7UYxbbrVg3-JZdKOWPcYFimFc677FMG4x; log=; \
				Hm_lvt_78c58f01938e4d85eaf619eae71b4ed1=1548080158; \
				Hm_lpvt_78c58f01938e4d85eaf619eae71b4ed1=1548080196; \
				Hm_lvt_60bad21af9c824a4a0530d5dbf4357ca=1548080175; \
				Hm_lpvt_60bad21af9c824a4a0530d5dbf4357ca=1548080196; \
				Hm_lvt_f79b64788a4e377c608617fba4c736e2=1548080175; \
				Hm_lpvt_f79b64788a4e377c608617fba4c736e2=1548080196; \
				vvvv=1"
	):
		""" 定义构造函数传入可变参数 """
		self.userAgent = userAgent
		self.cookie = cookie
		
		""" 定义常用的固定参数 """
		self.date = time.strftime("%Y-%m-%d")							 # 获取类初始化的时间
		self.workSpace = os.getcwd()									 # 获取工作目录
		self.errorLog = "Error_Log.txt"
		self.mainURL = "http://www.10jqka.com.cn/"
		self.dataURL = "http://data.10jqka.com.cn/"
		
		self.orderSuffix = "field/code/order/asc/page/{}/ajax/1/"
		
		self.stockFlowURL = self.dataURL + "funds/ggzjl/"
		self.conceptFlowURL = self.dataURL + "funds/gnzjl/"
		self.industryFlowURL = self.dataURL + "funds/hyzjl/"
		
		self.stockTableURL = self.stockFlowURL + self.orderSuffix
		self.conceptTableURL = self.conceptFlowURL + self.orderSuffix
		self.industryTableURL = self.industryFlowURL + self.orderSuffix
		self.headers = {
			"User-Agent":self.userAgent,
			"Cookie":self.cookie,
		}
		self.session = requests.Session()
		self.session.headers = self.headers
		
		""" 初始化操作 """
		self.session.get(self.mainURL)
		
	def parse_money_flow_stock(self,):									 # 获取A股个股资金流动
		self.session.get(self.dataURL)
		html = self.session.get(self.stockFlowURL).text
		soup = BeautifulSoup(html,"lxml")
		spans = soup.find_all("span")				 	
		ths = soup.find_all("th")							
		""" 将<th>标签中的string作为DataFrame的header """
		flag = False
		with open(r"{}\{}\money_flow_stock_{}.csv".format(self.workSpace,self.date,self.date),"a") as f:
			for th in ths:		
				aLabel = th.find_all("a")
				string = aLabel[0].string if len(aLabel) else th.string
				if flag: f.write(",{}".format(string))
				else:
					flag = True
					f.write(str(string))
			f.write("\n")		
		""" 遍历<span>标签获取总页数 """
		for span in spans:
			string = str(span.string)
			if len(string)>2 and string[:2]=="1/":	
				page = int(string[2:])
				break
		""" 获取资金流动信息 """
		for i in range(1,page+1):
			b = webdriver.Firefox()	
			b.get(self.stockTableURL.format(i))
			html = b.page_source
			soup = BeautifulSoup(html,"lxml")
			trs = soup.find_all("tr")
			with open(r"{}\{}\money_flow_stock_{}.csv".format(self.workSpace,self.date,self.date),"a") as f:
				for tr in trs[1:]:										 # 跳过第一个<tr>标签是因为第一行是表头
					flag = False
					tds = tr.find_all("td")
					for td in tds:
						string = str(td.string)
						string = string.replace(" ","").replace("\t","").replace("\n","")
						if flag: f.write(",{}".format(string))
						else: 
							flag = True
							f.write(string)
					f.write("\n")
			b.quit()
		return True

	def parse_money_flow_concept(self,):								 # 获取A股概念板块资金流动
		self.session.get(self.dataURL)
		html = self.session.get(self.conceptFlowURL).text
		soup = BeautifulSoup(html,"lxml")
		spans = soup.find_all("span")				 	
		ths = soup.find_all("th")							
		""" 将<th>标签中的string作为DataFrame的header """
		flag = False
		with open(r"{}\{}\money_flow_concept_{}.csv".format(self.workSpace,self.date,self.date),"a") as f:
			for th in ths:		
				aLabel = th.find_all("a")
				if len(aLabel): 										 # 概念板块与行业板块读取表头的代码如此笨拙因为与个股的方法在这里竟然只能拿到None,而且两者格式一模一样,让我很奇怪
					tag = str(aLabel[0])
					index1 = tag.find(">")
					index2 = tag.find("<",index1)
					string = tag[index1+1:index2]
				else: string = th.string
				if flag: f.write(",{}".format(string))
				else:
					flag = True
					f.write(str(string))
			f.write("\n")		
		""" 遍历<span>标签获取总页数 """
		for span in spans:
			string = str(span.string)
			if len(string)>2 and string[:2]=="1/":	
				page = int(string[2:])
				break
		""" 获取资金流动信息 """
		for i in range(1,page+1):
			b = webdriver.Firefox()	
			b.get(self.conceptTableURL.format(i))
			html = b.page_source
			soup = BeautifulSoup(html,"lxml")
			trs = soup.find_all("tr")
			with open(r"{}\{}\money_flow_concept_{}.csv".format(self.workSpace,self.date,self.date),"a") as f:
				for tr in trs[1:]:										 # 跳过第一个<tr>标签是因为第一行是表头
					flag = False
					tds = tr.find_all("td")
					for td in tds:
						string = str(td.string)
						string = string.replace(" ","").replace("\t","").replace("\n","")
						if flag: f.write(",{}".format(string))
						else: 
							flag = True
							f.write(string)
					f.write("\n")
			b.quit()
		return True

	def parse_money_flow_industry(self,):								 # 获取A股概念板块资金流动
		self.session.get(self.dataURL)
		html = self.session.get(self.industryFlowURL).text
		soup = BeautifulSoup(html,"lxml")
		spans = soup.find_all("span")				 	
		ths = soup.find_all("th")							
		""" 将<th>标签中的string作为DataFrame的header """
		flag = False
		with open(r"{}\{}\money_flow_industry_{}.csv".format(self.workSpace,self.date,self.date),"a") as f:
			for th in ths:		
				aLabel = th.find_all("a")
				if len(aLabel): 										 # 概念板块与行业板块读取表头的代码如此笨拙因为与个股的方法在这里竟然只能拿到None,而且两者格式一模一样,让我很奇怪
					tag = str(aLabel[0])
					index1 = tag.find(">")
					index2 = tag.find("<",index1)
					string = tag[index1+1:index2]
				else: string = th.string
				if flag: f.write(",{}".format(string))
				else:
					flag = True
					f.write(str(string))
			f.write("\n")		
		""" 遍历<span>标签获取总页数 """
		for span in spans:
			string = str(span.string)
			if len(string)>2 and string[:2]=="1/":	
				page = int(string[2:])
				break
		""" 获取资金流动信息 """
		for i in range(1,page+1):
			b = webdriver.Firefox()	
			b.get(self.industryTableURL.format(i))
			html = b.page_source
			soup = BeautifulSoup(html,"lxml")
			trs = soup.find_all("tr")
			with open(r"{}\{}\money_flow_industry_{}.csv".format(self.workSpace,self.date,self.date),"a") as f:
				for tr in trs[1:]:										 # 跳过第一个<tr>标签是因为第一行是表头
					flag = False
					tds = tr.find_all("td")
					for td in tds:
						string = str(td.string)
						string = string.replace(" ","").replace("\t","").replace("\n","")
						if flag: f.write(",{}".format(string))
						else: 
							flag = True
							f.write(string)
					f.write("\n")
			b.quit()
		return True

if __name__ == "__main__":
	print("测试开始...")
	sf = StraightFlush()
	sf.parse_money_flow_stock()
	sf.parse_money_flow_concept()
	sf.parse_money_flow_industry()

		

 

 

  • 8
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。
如果您下载了本程序,但是该程序无法运行,或者您不会部署,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用的) 爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值