企业工商数据源站点:无验证无拦截,批量获取工商数据完整方案
前言最近在做一个企业信息批量采集的小工具本意是去找现成的API。API还没正式接入先顺手在官网搜了几家公司试试数据质量。搜了几条之后看了一眼URL结构挺规整的就用 requests 拉了一页试试。结果直接返回了 HTML没有验证码没有跳转什么都没拦。后面又加了几层还是没拦。既然反爬约等于没有那就顺便看看能从页面上拿到哪些数据。文章目录前言一、网站长什么样能查到什么二、爬虫实战代码直接跑三、2点风险提示四、有些数据爬虫拿不到还是要接API一、网站长什么样能查到什么网站在这里鲸海数据首页就有非常明显的搜索框支持输入公司名称、法人名字或产品关键词。返回的是基础工商信息公司名称、统一社会信用代码、法定代表人、注册资本、成立日期、注册地址、经营状态、所述行业、经营范围这些字段都有。对于做数据清洗、客户筛选、初步市场分析的场景来说这些字段已经够用了。二、爬虫实战代码直接跑既然网站不设防那就不客气了。用 requests BeautifulSoup 写一个简单的爬虫批量爬取企业基础信息。importcsvimportjsonimportreimporttimefromurllib.parseimportquoteimportrequests# 鲸海数据(kqdaas.com)是 Next.js Server Action 接口# - 不是普通 GET 返回 HTML而是 POST /search 带 next-action 头# body 里的 keywords 才是真正的搜索词返回 RSC 流式文本。# - 真正的数据在以 1: 开头的那行 JSON 里data.records。# - NEXT_ACTION / COOKIE(尤其 hh-token 登录态) 来自浏览器抓包失效需重新抓包替换。BASE_URLhttps://www.kqdaas.com/search# 搜索关键词列表KEYWORDS[科技,信息,数据]OUTPUT_CSVcompany_data.csvHEADERS{accept:text/x-component,content-type:text/plain;charsetUTF-8,origin:https://www.kqdaas.com,referer:BASE_URL,next-action:7f4db410c3cc3eabe9c3ae6dd4b83ade5bd1c26d8d,next-router-state-tree:(%5B%22%22%2C%7B%22children%22%3A%5B%22(local)%22%2C%7B%22children%22%3A%5B%22search%22%2C%7B%22children%22%3A%5B%22__PAGE__%22%2C%7B%7D%2Cnull%2Cnull%5D%7D%2Cnull%2Cnull%5D%7D%2Cnull%2Cnull%5D%7D%2Cnull%2Cnull%2Ctrue%5D),user-agent:(Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36),Cookie:(__bid_n19eba682f8b6864d065fd9; hh-tokenhanhai-local-32960d96fc2ee62271c544a21f95c3de; nb-referrer-hostnamewww.kqdaas.com),}defparse_records(text):从 RSC 流式响应里取出 data.records。 响应每行形如 id:json只有一行 JSON 含 data.records。 只能按 \\n 切分splitlines() 会在记录内的 Unicode 行分隔符(\\x85 等)处截断 JSON。 forlineintext.split(\n):_,sep,payloadline.partition(:)ifnotsepornotpayload.startswith({):continuetry:datajson.loads(payload).get(data)exceptjson.JSONDecodeError:continueifisinstance(data,dict)andrecordsindata:returndatareturnNonedefsearch(keyword):搜索关键词返回 data 字典(含 records / totalRecords)失败返回 None。# Server Action 入参结构固定多加 pageIndex/pageSize 等字段会让服务端返回 data:null# 必须与抓包 body 完全一致。URL 上的 keyword 仅用于路由真正搜索词在 body.keywords。bodyjson.dumps([{type:filter,keywords:keyword,businessLocation:$undefined,companyIndustry:$undefined,companyType:$undefined,foundTime:$undefined,registCapital:$undefined,operateState:$undefined,contactType:$undefined,companyScale:$undefined,}],ensure_asciiFalse)resprequests.post(f{BASE_URL}?keyword{quote(keyword)},headersHEADERS,databody.encode(utf-8),timeout15)resp.raise_for_status()resp.encodingutf-8# requests 会猜错编码导致中文乱码、JSON 解析失败returnparse_records(resp.text)defmain():results[]forkeywordinKEYWORDS:try:datasearch(keyword)exceptExceptionase:print(f关键词「{keyword}」出错:{e})continueifnotdata:print(f关键词「{keyword}」未解析到数据next-action / cookie 可能已失效需重新抓包)continueforrindata[records]:results.append({公司名称:re.sub(r/?strong,,r.get(companyName,)),# 去掉高亮标签统一社会信用代码:r.get(creditNumber,),法定代表人:r.get(juridicalPerson,),})print(f关键词「{keyword}」爬取完成本页{len(data[records])}条f总计可搜{data.get(totalRecords,0)}条)time.sleep(1)# 礼貌性延迟withopen(OUTPUT_CSV,w,newline,encodingutf-8-sig)asf:writercsv.DictWriter(f,fieldnames[公司名称,统一社会信用代码,法定代表人])writer.writeheader()writer.writerows(results)print(f总共爬取{len(results)}条数据已写入{OUTPUT_CSV})if__name____main__:main()连续跑了一大批数据几乎没有遇到限制这种佛系程度在现在的企业数据站里确实少见****没被封IP没有弹验证码未触发任何限速提示数据字段完整可用当然具体的选择器需要大家自己去页面里看一下不同网站的HTML结构不一样这里只是给个框架。三、2点风险提示上面这套能跑通但有几点还是得提醒一下。一个是时效性。这种几乎不设防的状态大概率不会一直持续。哪天流量上来了或者运维随手加了个限流可能就没了。如果你现在手头有数据采集的需求趁早。另一个是合规。爬之前最好看一眼 robots.txt请求频率控制一下代码里写个 time.sleep(1) 不费事仅限合法合规用途。尊重数据版权大规模商业化使用建议走官方API四、有些数据爬虫拿不到还是要接API如果你需要的是更深入的维度比如司法风险、招投标记录、知识产权布局、资质证书、舆情信息这些爬虫拿不到还是得靠API。鲸海数据的API我顺手也测了一下注册就送的1000次免费额度是全平台通用的不是那种只开放一两个接口的阉割版。有深度查询需求的朋友可以顺便把API额度也领了。接口维度也比较多企业服务相关的数据基本都有我交叉测试了几个维度精确度和及时性都还可以。接口是标准的RESTful风格用GET请求加Header鉴权就能调Python几行代码的事。每个接口还有在线调试功能和详细的JSON 返回示例方便你检查验证数据结构、字段完整性和参数逻辑。比如「招投标信息列表」接口的JSON 返回示例如下大概就这样有这方面数据需求的朋友趁着反爬还没上、API 有免费额度早点去占个位传送门