天眼连接你我

2019-09-20 15:12:47 浏览数 (1)

天眼连接你我

0.前言1.字体映射2.动态kg3.作者的话

0.前言

最近读者想让我多发点爬虫文章,实在是时间原因,让各位就等了,我一口气,继续研究字体反爬策略,本文是基于天眼进行初探,后文待续。

今天的目标很简单,复习昨日的猫眼反爬虫策略,并且加以实战运用 ,针对不同情形如何处理,以及最最重要的:我发现了我研究的知识图谱领域的应用场景,看下面的一张图:

没错,这就是我研究的知识图谱,简称KG,之前发过一篇文章用d3可视化,我查看了这个网站,也是用的d3,哈哈,是不是之前的d3用到了呢!

时间总是给有准备的人,好像不对,机会总给有准备的人,如果你掌握了,是不是会更加主动呢?

总结一下需求:第一:字体反爬;第二:kg数据;

那么我们来开张,实战吧!

1.字体映射

思路

这个网站据说很难爬,而且IP会封杀的有点厉害,所以我自己搞了个IP池,去爬,一定不要裸奔

昨天我们知道字体不是一一对应关系的,那么对于今天的你会发现,是一一映射的(为什么,看后面),那么我们先来看一下网站实际访问的情形:

看上面两个图,发现不匹配啊!这就是该网站使用自定义字体通过映射出来的表现,我们需要得到映射关系,进而反爬获取真实字体。

接下来我们该怎么解决呢,肯定是找字体相关文件,在html中是css中自定义字体或者直接写进网页,那么我们通过筛选出css信息或者直接查看网页源码来找到相应的字体文件,但是源码不好找啊,这里我就用了css筛选法。

看到没,有一个font.css,我们发现woff格式字体链接了,我们只需要把他下载下来即可,这里可以手动复制链接,直接下载,或者使用我下面给出的代码,自动化下载!

有人会问上述那么多链接,选择哪个,这里就在看一下font筛选,看到对应的字体文件,就可以确定下载哪个链接了!

然后打开

http://fontstore.baidu.com/static/editor/index.html

导入woff字体,查看映射关系。

我们看到有汉字。。发现了没,这个网站的反爬虫贼强!我们只是初探!

网页刷新几次会发现字体链接,所以确定是一一映射关系!这里我们将0到9进行一一对应映射。

接下来,让我们畅游代码世界!

实现

封装

代码语言:javascript复制
class tianyan_Spider():
    def __init__(self):
        headers = {
            'User-Agent': '填入你的浏览器User-Agent',
        }
        self.headers = headers

以下的所有代码都是基于这个类的封装!

代理池

下面是哪IP跟端口去构造代理,最终形式为:

{'http': 'http://95.130.38.4:32920'}

代码语言:javascript复制
def get_proxy(self):
    li_proxy = ["43.242.242.176:43203","158.174.63.117:55535","95.170.157.97:30077","91.214.140.15:32231","94.243.140.162:40960","95.130.38.4:32920"]
    proxy_all = []
    for i in li_proxy:
        dict_proxy = {}
        dict_proxy['http']='http://' i
        proxy_all.append(dict_proxy)
    # {'http': 'http://95.130.38.4:32920'}
    print(proxy_all)
    return proxy_all

获取html

这里要说明一下,我在raw_html处直接是get一下,没有继续获取text或者content内容,原因在于,为了后面重复使用这个方法,使得逻辑的严谨性跟封装性更好!

代码语言:javascript复制
def get_html(self,url):
    proxy = self.get_proxy()
    proxy_len = len(proxy)
    for i in range(proxy_len):
        t = random.randint(0,  proxy_len- 1)
        raw_html = requests.get(url, headers=self.headers,proxies=proxy[t])
        # 判断IP能不能用
        if not raw_html.content:
            continue
        print("正在使用IP:" str(proxy[t]))
        return raw_html

下载字体

注意:一定要用content不能用text,content返回bytes,写入以wb正常,如果为text,则报错!

代码语言:javascript复制
def save_font(self,url):
    font = self.get_html(url).content
    with open('./tianyan.woff',"wb") as f:
        f.write(font)

映射关系

这里自己写的一个算法,用来将字符替换掉,如果各位大佬有更优的算法,欢迎讨论!

算法思路是定义新字符串,如果这个字符出现在关系字典中,则用value替换掉,并放入新字符串中,如果当前这个字符没出现在关系字典中,则说明不需要转换,直接放入新字符就可以。

代码语言:javascript复制
def replace_Str(self,raw_str):
    rel_dict = {
        "0":"0","3":"1","4":"2","9":"3","6":"4",
        "2":"5","1":"6","8":"7","7":"8","5":"9",
    }
    newstr = ""
    for i in raw_str:
        if i in rel_dict:
            newstr =i.replace(i,rel_dict[i])
        else:
            newstr =i
    return newstr

替换内容

将非正常内容通过上述算法替换掉即可!

代码语言:javascript复制
def get_Content(self,url):
    raw_html = self.get_html(url).text
    selector = etree.HTML(raw_html)
    regist_money = selector.xpath('//div[@id="_container_baseInfo"]/table[1]/tbody/tr[1]/td[2]/div[1]/text()')[0]
    print(regist_money)
    regist_content = selector.xpath('//div[@id="_container_baseInfo"]/table[1]/tbody/tr[1]/td[2]/div[2]/text/text()')[0]
    regist_content = self.replace_Str(regist_content)
    print(regist_content)
    regist_time = selector.xpath('//div[@id="_container_baseInfo"]/table[1]/tbody/tr[2]/td/div[1]/text()')[0]
    print(regist_time)
    regist_time_content = selector.xpath('//div[@id="_container_baseInfo"]/table[1]/tbody/tr[2]/td/div[2]/text/text()')[0]
    regist_time_content = self.replace_Str(regist_time_content)
    print(regist_time_content)

验证

网站截图如下:

反爬结果如下:

2.动态kg

思路

分析网页发现,那个图d3是动态的,所以猜想在xhr中,于是来到xhr筛选,我们发现了我们先想要的数据!

没错,就是这个json数据!

实现

json获取与存储!

代码语言:javascript复制
def get_kgJson(self,url):
    raw_html = self.get_html(url).json()
    #写json文件
    with open('kg.json', "w") as f:
        # indent缩进,separators是否去除空格,默认去除!
        f.write(json.dumps(raw_html["data"], sort_keys=False, indent=4, separators=(',', ': '), ensure_ascii=False))

哈哈,有数据了,以后可以搞个大的知识图谱可视化!

0 人点赞