写这篇文章之前我用python爬取了东方财富网上市公司的利润报表,闲来蛋疼我又写了一个爬同花顺官网上面的上市公司利润报表,这次我用的是requests包,下面碰到一些问题记录一下,发送请求前要构造请求头部信息:
url = 'http://data.10jqka.com.cn/ajax/yjgg/date/2020-03-31/board/ALL/field/DECLAREDATE/order/desc/page/'+str(page)+'/ajax/1/free/1/'
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Encoding':'gzip, deflate',
'Cookie':'Hm_lvt_60bad21af9c824a4a0530d5dbf4357ca=1593051856,1593077609; Hm_lpvt_60bad21af9c824a4a0530d5dbf4357ca=1593077609; Hm_lvt_78c58f01938e4d85eaf619eae71b4ed1=1593051856,1593077610; Hm_lpvt_78c58f01938e4d85eaf619eae71b4ed1=1593077610; Hm_lvt_f79b64788a4e377c608617fba4c736e2=1593051856,1593077610; Hm_lpvt_f79b64788a4e377c608617fba4c736e2=1593077610; v=AuqykmjLQFHqYsy92WH2_hWNO1uPW340YP3iL3SilITJoITNXOu-xTBvMkpH',
'Accept-Language':'zh-CN,zh;q=0.9',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
'Connection':'keep-alive',
'Host': 'data.10jqka.com.cn',
'If-None-Match':'5ef343c9-1362d',
'Upgrade-Insecure-Requests':'1',
}
response = requests.get(url,headers=headers)
接着调用:requests.get(url,headers=headers) 发送请求中附带头部信息,同花顺官网首先判断你是不是有个爬虫机器人,重要的信息是User-Agent 没有的话,会判断是一个机器人,我这里设置的是谷歌浏览器,加上头部信息后,可以获取到返回信息了,但是最多只能爬取5,6页的数据,之后IP就被拉黑,过几分钟才能继续爬取,显然这是同花顺对爬虫第二层限制,网上查询了一些大神用代理IP的方式还是只能爬取5,6页数据,通过我的观察同花顺的每次访问的请求中必带一个Cookie和If-None-Match字段,而且你点击每一页的时候Cookie和If-None-Match都会变化一次,我怀疑同花顺在后台会判断Cookie的值,同一个Cookie的值最多只能访问5次左右,如果可以获取到页面的Cookie的值和If-None-Match的值应该就可以无限爬取,这里我还是换回原来的包号称只要页面可以访问到的页面都能爬的selenium包,这是一个模拟人类自动点击浏览器然后爬取浏览器页面数据的包,代码如下:
#新建一个谷歌浏览器
chrome_options = webdriver.ChromeOptions()
#打开浏览器
#chrome_options.add_argument('--headless')
chrome_options.add_argument("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36")
browser = webdriver.Chrome(options=chrome_options)
wait = WebDriverWait(browser, 20)
url = "http://data.10jqka.com.cn/ajax/yjgg/date/2020-03-31/board/ALL/field/DECLAREDATE/order/desc/page/1/ajax/1/free/1/"
response = bowser.get(url)
同样用这个包也是要设置User-Agent,不然还是会爬不到数据,最后经过不懈努力我爬取了同花顺官网所有上市公司一季度利润表并且存储到Oracle中,怎么样是不是很简单?关键是设置User-Agent信息,然后强大的selenium包会模拟人类访问浏览器,所以不用构造Cookie和If-None-Match现在我是体会到Python强大的地方。
def main():
con = conn_Db("XXXXX","XXXXXX","127.0.0.1:1521/XE")
cur = con.cursor()
dir=r'D:\测试python\同花顺上市公司利润表.xls'
# 此处获取目录中所有的文件名称
book = xlrd.open_workbook(dir)
for i in range(len(book.sheets())):
table = book.sheet_by_index(i)
rows_num = table.nrows #获取行数
cols_num = table.ncols #获取列数
list = {}
for j in range(1,table.nrows):
Database_SHARESLRB.CODE = int(table.cell(j,1).value)
Database_SHARESLRB.NAME = table.cell(j,2).value
#处理时间格式
date = datetime(*xldate_as_tuple(table.cell_value(j,3),0))
data_time = date.strftime('%Y-%m-%d') #('%Y/%m/%d %H:%M:%S')
Database_SHARESLRB.NOTE_DATE = data_time
Database_SHARESLRB.YYSR = getAllMoney(table.cell(j,4).value)
Database_SHARESLRB.YYSR_TB = table.cell(j,5).value
Database_SHARESLRB.YYSR_JDHB = table.cell(j,6).value
Database_SHARESLRB.JLR = getAllMoney(table.cell(j,7).value)
Database_SHARESLRB.JLR_TB = table.cell(j,8).value
Database_SHARESLRB.JLR_JDHB = table.cell(j,9).value
Database_SHARESLRB.MGSY = table.cell(j,10).value
Database_SHARESLRB.MGJZC = table.cell(j,11).value
Database_SHARESLRB.JZCSY = table.cell(j,12).value
Database_SHARESLRB.XJLL = table.cell(j,13).value
Database_SHARESLRB.XSMLL = table.cell(j,14).value
Database_SHARESLRB.GD = table.cell(j,15).value
data = {
'CODE':''+str(Database_SHARESLRB.CODE )+'',
'NAME':"'"+str(Database_SHARESLRB.NAME)+"'",
'NOTE_DATE':"to_date('"+Database_SHARESLRB.NOTE_DATE+"','yyyy-MM-dd')",
'YYSR':''+str(Database_SHARESLRB.YYSR)+'',
'YYSR_TB':''+str(Database_SHARESLRB.YYSR_TB)+'',
'YYSR_JDHB':"'"+str(Database_SHARESLRB.YYSR_JDHB)+"'",
'JLR':''+str(Database_SHARESLRB.JLR)+'',
'JLR_TB':''+str(Database_SHARESLRB.JLR_TB)+'',
'JLR_JDHB':"'"+str(Database_SHARESLRB.JLR_JDHB)+"'",
'MGSY':''+str(Database_SHARESLRB.MGSY)+'',
'MGJZC':''+str(Database_SHARESLRB.MGJZC)+'',
'JZCSY':''+str(Database_SHARESLRB.JZCSY)+'',
'XJLL':''+str(Database_SHARESLRB.XJLL)+'',
'XSMLL':''+str(Database_SHARESLRB.XSMLL)+'',
'GD':"'"+str(Database_SHARESLRB.GD)+"'",
}
tableName = "SHARES_LRB"
keys = ", ".join(data.keys())
values = ', '.join(data.values())
#values = tuple(data.values()) 转化成元组
check_sql = "select code from SHARES_LRB where code = '"+str(Database_SHARESLRB.CODE)+"'"
count = cx_query(cur,check_sql)
count = count.fetchone()
if count is None:
sql = "INSERT INTO {table}({key}) values({value})".format(table=tableName,key=keys,value=values)
print(sql)
cx_excueSql(cur,sql)
#提交事务
exe_commit(cur)
else:
pass
#获取每列的字段存到字典中
# for k in range(1,cols_num):
# list[k] = str(table.cell(j,k).value)
# for j in range(1,table.nrows):
# id = int(table.cell(j,0).value)
# shares_code = str(table.cell(j,2).value)
# shares_name = str(table.cell(j,3).value)
# print(shares_code)
conn_close(con,cur)