企查查python爬虫实例
前些日子尝试给朋友写了一个查询大批公司的统一社会信用码的爬虫程序,借助了很多网上的帖子,学习很多,现在也分享一下我用的python程序。
-
准备python库文件(python 3.7)
import importlib #提供import语句 import sys import time #提供延时功能 import xlrd #excel文件读取 import os import xlwt #excel文件写入 from xlutils.copy import copy #excel文件复制 from selenium import webdriver #浏览器操作库 importlib.reload(sys)
-
首先伪装成浏览器访问企查查网页,然后要手动登录一次,如果不登录不能查询企业的所有信息,而且限制查询次数。一开始尝试利用程序自动完成账号密码登录,可是登录界面的进度条始终出错,后来利用第三方QQ登录便解决了这一步,也只需要点击两次,最好把QQ在电脑上登录好,会自动检测登录的QQ账户,点击两次就行了。这样就不用手机扫码了。另外登录后会有个提示绑定微信的弹出框,关掉就好。
这部分代码:#伪装成浏览器,防止被识破 option = webdriver.ChromeOptions() option.add_argument('--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"') driver = webdriver.Chrome(options=option) #打开登录页面 driver.get('https://www.qichacha.com/user_login') time.sleep(20)#等待20s,完成手动登录操作 #手动登录操作
-
接下来我们会读取excel里面需要查询的公司列表,然后存入一个list里面,方便后面循环检索。
#从excel获取查询检索公司数据 worksheet = xlrd.open_workbook(u'test.xls')#excel放在同一个工作空间下 sheet1 = worksheet.sheet_by_name("CD类未拓展客户清单")#excel有多个sheet,检索该名字的sheet表格 rows = sheet1.nrows # 获取行数 inc_list = [] for i in range(1,rows) : data = sheet1.cell_value(i, 1) # 取第2列公司数据 inc_list.append(data) print(inc_list) #打印出来可检查获取的数据对不对 inc_len = len(inc_list)
-
然后就开始检索公司,这里有两个思路,1)将inc_list 里面的公司全部检索出来存在另一个data_list里面,最后在写回excel文件里;2)每检索一个公司就存回excel文件里并保存文件,然后再检索下一个再保存。显然第一个从程序上看效率更高,不用重复写入保存。但是在查询大量公司的情况下,一旦出现问题,之前查询的结果就没了,又得解决问题重新开始,这样效率反而会更低。所以我采用了第二种办法,虽然效率低点,但是我要查询几千个公司的数据,万一中途出现问题,不用从头开始。
#写回数据 writesheet1 = copy(worksheet)# 这里复制了一个excel,没有直接写回最初的文件。 writesheet2 = writesheet1.get_sheet(1)#同样获得第一个sheet style = xlwt.easyxf('font:height 240, color-index red, bold on;align: wrap on, vert centre, horiz center'); #开启爬虫 for i in range(inc_len): txt = inc_list[i] #循环获取list里面的公司名称 time.sleep(1) #等待加载 ……
-
程序模仿浏览器进行检索公司中,会先搜索该公司,然后会检索到很多相关的企业,一般检索出来的相关列表第一个就是需要的公司,这里需要程序模拟人工的点击。
该部分代码:if (i==0): #向搜索框注入文字 driver.find_element_by_id('searchkey').send_keys(txt) #单击搜索按钮 srh_btn = driver.find_element_by_xpath('//*[@id="indexSearchForm"]/div/span/input') srh_btn.click() else: #清楚搜索框内容 driver.find_element_by_id('headerKey').clear() # 向搜索框注入下一个公司地址 driver.find_element_by_id('headerKey').send_keys(txt) #搜索按钮 srh_btn=driver.find_element_by_xpath('/html/body/header/div/form/div/div/span/button') srh_btn.click()
这里利用了Xpath路径获取页面数据或者按钮的位置,在我们所要查询的数据或者按钮方框那里右击-检查就会进入网页的html界面,并会直接标出我们查询的位置对应的html代码,然后在代码处右击-copy-xpath,就可将该位置的路径复制到剪贴板上,后面获取数据也是利用这个办法。
-
接着进入了公司信息界面,找到我们需要的数据,同样利用上面的方法便可以获取数据对应的xpath路径,然后用指令获取这路径上的数据就可以了。
可实际操作我利用基本信息里面的统一社会信用码的xpath路径总是获取的数据为空,从网上了解应该是这个地方利用了ajax的技术将数据存放在另一个url地址,可以在network里面找到该地址,无奈我没有找到这个url地址,但是我发现从上图标出的企业发展里面可以从统一社会信用码对应的xpath路径获取数据,便就在程序中多操作一步进入到企业发展界面里面,这里面的年报数据里面包含了信用码。不好的地方就是有的公司没有最近年份的年报数据,便也检索不到相关信息了,就必须要检测其余年份的年报数据,就还需要增加几个判断语句。我这里就直接检索最近年份的数据,如果检索不到就置none
该部分代码:try: # 获取网页地址,进入 inner=driver.find_element_by_xpath('//*[@id="search-result"]/tr[1]/td[3]/a').get_attribute("href") driver.get(inner) time.sleep(2) # 弹出框按钮 try: try: srh_btn= driver.find_element_by_xpath('//*[@id="firstepdadModal"]/div/div/div[2]/button') srh_btn.click() except: srh_btn= driver.find_element_by_xpath('//*[@id="firstcaseModal"]/div/div/div[2]/button') srh_btn.click() except: pass try: # 转到企业发展 tag = driver.find_element_by_xpath('//*[@id="report_title"]') tag.click() time.sleep(2) #获取首个企业信用码 try: credit_code= driver.find_element_by_xpath('//*[@id="0"]/table[1]/tbody/tr[1]/td[4]').text except: credit_code='none' except: credit_code = 'none' except: credit_code = 'none'
这里添加了很多try,excep 判断语句,主要是为了排除可能出现的错误以及自动关闭弹出框,让程序可是正常运行下去。流程图如下:
-
将获取的数据存入excel对应的位置,并保存,开始下一次检索。
print(credit_code) writesheet2.write(i+1, 15, credit_code) # 将数据写入第16列 writesheet1.save(u'test2.xls') driver.close() #关闭浏览器
至此,这个简易的爬虫程序就写完了。总的来说,这种爬虫程序采用的selenium库对于我这样的新手来说比较友好,就是总的效率不是很高,而且访问频率高了,也会被企查查给识别到,不过过一会再运行一下就行了,而且也不用从头来,之前的数据也都保存了。实测第一次检测了1516个公司没有被中止,紧接著第二次检测的时候在900多次的时候被中止。网上也有很多利用Beautiful Soup,requests等库来做的,有机会也要再去尝试学习。另外说明的就是搜索的公司名称最好要完整,不要带地址啥的,这样可以提高检索到的概率,当然也有很多个体经营户是没有许多信息的,自然是检索不到。
谢谢浏览!也欢迎转载!最后附上完整代码:
import importlib #提供import语句 import sys import time #提供延时功能 import xlrd #excel文件读取 import os import xlwt #excel文件写入 from xlutils.copy import copy #excel文件复制 from selenium import webdriver #浏览器操作库 importlib.reload(sys) #伪装成浏览器,防止被识破 option = webdriver.ChromeOptions() option.add_argument('--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"') driver = webdriver.Chrome(options=option) #打开登录页面 driver.get('https://www.qichacha.com/user_login') time.sleep(20)#等待20s,完成手动登录操作 # 手动登录操作 #从excel获取查询单位 worksheet = xlrd.open_workbook(u'test.xls') sheet1 = worksheet.sheet_by_name("CD类未拓展客户清单")#excel有多个sheet,检索该名字的sheet表格 rows = sheet1.nrows # 获取行数 inc_list = [] for i in range(1,rows) : data = sheet1.cell_value(i, 1) # 取第2列数据 inc_list.append(data) print(inc_list) inc_len = len(inc_list) #写回数据 writesheet1 = copy(worksheet)# 这里复制了一个excel,没有直接写回最初的文件。 writesheet2 = writesheet1.get_sheet(1)#同样获得第一个sheet style = xlwt.easyxf('font:height 240, color-index red, bold on;align: wrap on, vert centre, horiz center'); #开启爬虫 for i in range(inc_len): txt = inc_list[i] time.sleep(1) if (i==0): #向搜索框注入文字 driver.find_element_by_id('searchkey').send_keys(txt) #单击搜索按钮 srh_btn = driver.find_element_by_xpath('//*[@id="indexSearchForm"]/div/span/input') srh_btn.click() else: #清楚搜索框内容 driver.find_element_by_id('headerKey').clear() # 向搜索框注入下一个公司地址 driver.find_element_by_id('headerKey').send_keys(txt) #搜索按钮 srh_btn = driver.find_element_by_xpath('/html/body/header/div/form/div/div/span/button') srh_btn.click() try: # 获取网页地址,进入 inner = driver.find_element_by_xpath('//*[@id="search-result"]/tr[1]/td[3]/a').get_attribute("href") driver.get(inner) time.sleep(2) # 弹出框按钮 try: try: srh_btn = driver.find_element_by_xpath('//*[@id="firstepdadModal"]/div/div/div[2]/button') srh_btn.click() except: srh_btn = driver.find_element_by_xpath('//*[@id="firstcaseModal"]/div/div/div[2]/button') srh_btn.click() except: pass try: # 转到企业发展 tag = driver.find_element_by_xpath('//*[@id="report_title"]') tag.click() time.sleep(2) #获取首个企业信用码 try: credit_code = driver.find_element_by_xpath('//*[@id="0"]/table[1]/tbody/tr[1]/td[4]').text except: credit_code='none' except: credit_code = 'none' except: credit_code = 'none' print(credit_code) writesheet2.write(i+1, 15, credit_code) # 第16列数据sheet1.write(i, j, data[j]) writesheet1.save(u'test2.xls') driver.close()