python 爬取天眼查,有效应对字体反爬

作为一个新生代的爬虫小菜鸡,应该多学习一些爬虫的奇技淫巧。

本篇博文旨在经验交流,如果侵犯利益,请告知删除。


作为企业信息的汇总之地,天眼查和企查查一直被大量的爬虫爱好者光顾,于是各种反爬措施层出不穷,极验二代三代验证码,字体反爬,JS加密等等手段,但是,苍蝇不叮没缝的蛋,总有办法应对这些反爬措施。

1.先来看看登录页面,这里登录有个极验二代的验证码,可以推导轨迹进行selenium模拟拖动。

但是我们可以尝试看一下页面,发现登录不登录都看不到第六页,贫穷限制了自己的想象,两个网站都要开VIP才能看之后的页面,于是我们其实可以考虑不登陆网站的方法,这样也不用登录就可以愉快抓取5页了。

抓取的url:https://www.tianyancha.com/search/p6?key=知乎-----------------------p6代表第6页,之后类推,key后面带关键字

2.好的,装模做样分析一波就可以开干了,我们在这个搜索页面只需要两个值就可以了,公司名字和公司链接,但是这里需要提醒的是,公司名是text,偶尔触发字体反爬(也就是加了tyc-num的属性后)会变成其他文本,所以我们可以考虑用左边图片的替代文本alt的值来作为公司名字。

def get_url(keyword,page):
    global count
    res = requests.get('代理池代理池')
    proxy = json.loads(res.text)
    url= "https://www.tianyancha.com/search/p{}?key={}".format(page, keyword)
    response = requests.get(url, headers=headers,  proxies=proxy)
    if response.status_code == 200:
        doc = pq(response.text)
        items = doc("#web-content > div > div.container-left > div.search-block.header-block-container > div.result-list.sv-search-container > div").items()
        data = {}
        for item in items:
            #利用图片的填充文本获取公司名字
            img = item("div > div.left-item > div > div.logo.-w88 > img")
            data['name'] = img.attr("alt").replace("<em>", "").replace("</em>", "")
            # 获取公司url
            a = item("div > div.content > div.header > a")
            data['url'] = a.attr("href")
            count = count + 1
            print(data, count)
            yield data

这里进行了统计,前五页爬取的count为100,与原页面每页20相同,证明没有漏的公司,这个也有一个弊端,像我这里加了个代理,不然偶尔会要求登录,当然也可以不加,加个cookies也是可以的,复制自己登录后的cookies放到get中,一般都利用字典推导式来做cookies。

# 不带上Cookie就访问不了这个页面
cookie = "aliyungf_tc=AQAAAIub1w4uFgcAikIYdAQzI8dY9mjU; ssuid=6115264187; bannerFlag=undefined; Hm_lvt_e92c8d65d92d534b0fc290df538b4758=1558404890; _ga=GA1.2.418827579.1558404891; _gid=GA1.2.1891485528.1558404891; csrfToken=lpQFxeRdjmGjcXoLdq3aGZsV; TYCID=46901ee07b6e11e9be27abfcc402465e; undefined=46901ee07b6e11e9be27abfcc402465e; RTYCID=3893429da45240babd4ebcf58969d8c0; CT_TYCID=4135fc93e4a744efb4baa63d20fbf539; _gat_gtag_UA_123487620_1=1; token=a2e453b73bdb483689cb1e653afc9501; _utm=ec1d80bc6b174ee0b1244b21be75a067; tyc-user-info=%257B%2522claimEditPoint%2522%253A%25220%2522%252C%2522myAnswerCount%2522%253A%25220%2522%252C%2522myQuestionCount%2522%253A%25220%2522%252C%2522signUp%2522%253A%25220%2522%252C%2522explainPoint%2522%253A%25220%2522%252C%2522privateMessagePointWeb%2522%253A%25220%2522%252C%2522nickname%2522%253A%2522%25E7%2599%25BD%25E8%25B5%25B7%2522%252C%2522integrity%2522%253A%25220%2525%2522%252C%2522privateMessagePoint%2522%253A%25220%2522%252C%2522state%2522%253A%25220%2522%252C%2522announcementPoint%2522%253A%25220%2522%252C%2522isClaim%2522%253A%25220%2522%252C%2522vipManager%2522%253A%25220%2522%252C%2522discussCommendCount%2522%253A%25220%2522%252C%2522monitorUnreadCount%2522%253A%25224%2522%252C%2522onum%2522%253A%25220%2522%252C%2522claimPoint%2522%253A%25220%2522%252C%2522token%2522%253A%2522eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxMzQyMjgyMDcyMSIsImlhdCI6MTU1ODU3NDEyMSwiZXhwIjoxNTkwMTEwMTIxfQ.QtfsbeQnO7hclIN8u91-lGGjpA9IAnGD7oV6iUT6X3L-9MASeA2_sg6n3HY1CMuuEs9sXHQibat0Ovm2WGbgkA%2522%252C%2522pleaseAnswerCount%2522%253A%25220%2522%252C%2522redPoint%2522%253A%25220%2522%252C%2522bizCardUnread%2522%253A%25220%2522%252C%2522vnum%2522%253A%25220%2522%252C%2522mobile%2522%253A%252213422820721%2522%257D; auth_token=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxMzQyMjgyMDcyMSIsImlhdCI6MTU1ODU3NDEyMSwiZXhwIjoxNTkwMTEwMTIxfQ.QtfsbeQnO7hclIN8u91-lGGjpA9IAnGD7oV6iUT6X3L-9MASeA2_sg6n3HY1CMuuEs9sXHQibat0Ovm2WGbgkA; Hm_lpvt_e92c8d65d92d534b0fc290df538b4758=1558574102; cloud_token=33904acac4d444f694a3f0512fb7ca64; cloud_utm=c9a3948de7934cd9b148c0fca7ddcac3"
# 将上面哪个cookie转化成字典类型
cookie_dict = {i.split("=")[0]:i.split("=")[-1] for i in cookie.split("; ")}

这个cookies是我上周的,在登陆时有选保持一周登录的话就还可以使用,不过最稳妥的办法就是cookies+proxies.

这个时打印的页面,关键字是“百度”页数是5

3.一般我们会把这个url存入数据库中,称之为种子,不是那些mp4rmvb的种子,是对于我们下一步爬取的种子,接下来可以根据这个url来爬取企业具体信息了。这个详情页面大概率会出现字体反爬,也就是我之前说的tyc-num

刚开始我还觉得能拿title来继续做,到了后面发现经营范围这个字段真的是太烦了

而且这个在有cookies,sleep10秒以上的情况下还有机会给我个极验3代的验证码。。

虽然这个页面在我登录时也有机会出现的,但是这个页面让我有了一些思路,仔细看看这个return_url,这个是返回到我们刚刚的公司信息页面,也就是我们提交完验证码后跳转回公司详情页会有个reference

果然有这个,有了这个我就不用打极验三代验证码了,省了一笔小钱,而我们再看看网页源码,发现竟然没有加tyc-num这个属性了,于是我做个大胆推测,当我们绕过天眼查的机器人识别后,他们就会以为我们是正常用户了,所以页面上的反爬都消失了,当然没有换IP作死也有可能被查出来,尽量还是利用代理。

这里贴上我爬数据的源码,利用referer来绕过验证码以及字体反爬是个有效措施。我想要爬取字体加密的信息,这个有难度,之前也有尝试过破解字体加密(也就是我的fontchange),但是没办法自动化,得用机器学习来做ocr才可以,如果有兴趣可以查看项目源码(博文末尾)

def crawl_item(keyword):
    for item in db[keyword].find({}):
        sleep(random.randrange(1, 15))
        headers["Referer"] = "https://antirobot.tianyancha.com/captcha/verify?return_url=https%3A%2F%2Fwww.tianyancha.com%2Fcompany%"+ item["url"][35::] +"&rnd="
        response = requests.get(url=item["url"], headers=headers, cookies=cookie_dict)
        doc = pq(response.text)
        str1 = doc('.tyc-num').text()
        if str1:
            print(str1)
            str2 = fontchange(str1)
            print(str2)
        else:
            text2 = doc("#_container_baseInfo .table:nth-child(2)").text().split("\n")
            my_dict = {}
            my_dict["name"] = item["name"]
            for i in range(0, len(text2) - 1, 2):
                my_dict[text2[i]] = text2[i + 1]
            yield my_dict

记住,爬虫要健壮的话必须加上cookies和proxies,不然各大网站都可能因此封ip,短则1-2小时,长则1-3天,这样会超级难受的。https://github.com/triangle959/TianYanCha


贴一组字体反爬的图,运用逻辑在于项目内的fontchange,将网页的文字与font字体文件连接起来

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章