先来吐槽一下,突然接到一个任务,要我收集所有的联行行号,由于网络的原因,我开始访问页面都很慢,我就想着去网上找找现成的,结果CSDN上果然有好多人上传的,但是由于很早以前CSDN升级以后,账号全都要解封,我这个人记性不好,密码什么的都忘记了,连账号都模糊了,所以就让朋友帮忙下载,结果需要C币,我朋友的刚好还不够,我就很无奈了。再次想要写博客的时候,那时候我曾在CSDN和博客园犹豫过,后来选择博客园的主要原因是,改密码方便,这个密码我真记不住,每次需要输密码的时候,果断找回,然后重新来。但是CSDN的找回密码简直逆天的繁琐。言归正传:
联行行号,我的理解就是每个银行的注册编号,与银行名称一一对应且唯一。
目前能直观的得到数据的有两个网站,那么就相当于找到了数据源:
http://www.lianhanghao.com
http://www.eoeit.cn/lianhanghao/index.php
简单说一下上面两个数据源的区别:
第一点,1号数据源的响应速度快,2号数据源的响应速度慢;第二点,1号数据源中的数据有掺入别的字符,数据不纯,2号数据源的数据不含其他无用字符;第三点,1号数据源的数据结构相对完整,2号数据源的数据结构不一定完整;第四点,1号数据源的数据量少,2号数据源的数据量多(差的不是很多)
两个数据源的数据都抓了,基本的代码逻辑是一样的,直接上代码(python,稍微说一下,随着中基本上只使用一次的爬虫,没必要花很多时间写的很完整,只要不出大的问题,一次性过了就不要了,不用花太多时间架构代码)
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 # @Author : mario 5 # @File : bank_code_crawler.py 6 # @Project : reptillian 7 # @Time : 2018-09-10 20:47:35 8 # @Desc : File is ... 9 import datetime 10 import threading 11 12 import requests 13 from pyquery import PyQuery as pq 14 15 16 def get_data(i): 17 # 每个线程抓664页数据 18 print("第" + str(i) + "号启动线程") 19 file = open("线程" + str(i) + "收集的数据.txt", 'w', encoding="utf-8") 20 for page in range((i - 1) * 664, i * 664): 21 # for page in range(6455-1, 6455): # 这行代码用来补充数据 22 try: 23 url = "http://www.eoeit.cn/lianhanghao/index.php?page=" + str(page + 1) 24 response = requests.get(url, "b") 25 html = response.text 26 tbody = pq(html)("tbody") 27 trs = pq(tbody)("tr") 28 for tr in trs: 29 data = pq(tr)("td").text().replace(" ", ",") 30 file.write(data) 31 file.write(" ") 32 file.flush() 33 except Exception as e: 34 file.write("====抓去第"+str(page+1)+"页面数据异常 ") 35 print(e) 36 print("第" + str(page + 1) + "页数据") 37 file.close() 38 end_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') 39 print(end_time) 40 41 42 def init_threads(threads, number): 43 for i in range(0, number): 44 t = threading.Thread(target=get_data, args=(i + 1,)) 45 threads.append(t) 46 return threads 47 48 49 if __name__ == "__main__": 50 begin_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') 51 print(begin_time) 52 # 初始化线程 53 threads = [] 54 init_threads(threads, 10) 55 # 启动线程 56 for thread in threads: 57 thread.start()
以上就是整个爬虫的代码,核心的代码只有10行左右,线程是后来加上去的,但是基本上没有什么用。
补充说明:
第一点:10个线程太多了,还是会导致服务器拒绝连接,简单的解决方案就是,虽然定义了线程,但每次还是1个线程跑,比如:初始化的时候传入了threads和10,但是在初始化方法的for循环中写成 for i in range(9,number):我是懒得重新在写代码,对于一次性的,这样改我觉得方便,不用考虑后期维护什么的,因为这种一次性的爬虫是没有后期的。
第二点:代码第21行,是用来解决如下现象:比如,比如第2000页的数据请求时出了问题,那么我不想让程序停下来,继续抓2001页的数据,这样最后的结果就会少了一些页面的数据,最后用这个稍微补充一下,然后整理数据就可以了。
好像没有找到上传附件的地方,不过如果有谁需要可以联系我,大概数据在13W左右吧。