参考博客:http://www.cnblogs.com/eastonliu/p/9925652.html

实习僧招聘的网站采用了字体反爬,在页面上显示正常,查看源码关键信息乱码,如下图所示:

查看网页源码也是看不到关键信息:

查了一下是css3支持自定义字体,实习僧技术人员把一些字体换成了自定义的字体,浏览器上可以显示,后台就看不到了。

1.首先找到这些字体是在哪定义的。

右键查看网页源码,查找font-face,就会看到字体信息(加密的数据太多):

可以看到这些字体源是用了base64加密,用base64库进行解密,把解密后的字体文件保存到shixi.ttf中,下载一个字体软件FontCreator。链接:https://pan.baidu.com/s/1BPRhWYvOs6KFrgNQ4h7m_g 提取码:1fa4

1 def parse_ttf():
2 font_face = " 源码上的font-face"
3 b = base64.b64decode(font_face)
4 with open('shixi.ttf', 'wb') as f:
5 f.write(b)

用软件打开这个字体文件,可以右键-Captions-Codepoints选择排序方式:

可以看到这是网页替换的字体,例如:e588---1,ebbc---5.

2.接下来就是找到这些字体和源码中相应位置字符的对应关系。

ttf文件直接打不开,可以转换成xml文件打开或者用from fontTools.ttLib import TTFont 这个库打开。

1 def font_dict():
2 font = TTFont('shixi.ttf')
3 font.saveXML('shixi.xml')

打开shixi.xml,找到cmap,这里保存了编码和字体的对应关系。

接下来就是获取这种对应关系,code所示的就是网页上的源码形式,但是用getBestCmap()函数获取后又变成十进制的数了,所以需要用hex()函数将10进制整数转换成16进制,以字符串形式表示成原来的行是。

这里有一个坑,第一行的map没有用,如果不删除接下来没办法解析。

 1 def font_dict():
2 font = TTFont('shixi.ttf')
3 font.saveXML('shixi.xml')
4 ccmap = font['cmap'].getBestCmap()
5 print("ccmap:\n",ccmap)
6 newmap = {}
7 for key,value in ccmap.items():
8 # value = int(re.search(r'(\d+)', ccmap[key]).group(1)) - 1
9 #转换成十六进制
10 key = hex(key)
11 value = value.replace('uni','')
12 a = 'u'+'0' * (4-len(value))+value
13 newmap[key] = a
14 print("newmap:\n",newmap)
15 #删除第一个没用的元素
16 newmap.pop('0x78')
17 #加上前缀u变成unicode....
18 for i,j in newmap.items():
19 newmap[i] = eval("u" + "\'\\" + j + "\'")
20 print("newmap:\n",newmap)
21
22 new_dict = {}
23 #根据网页上显示的字符样式改变键值对的显示
24 for key, value in newmap.items():
25 key_ = key.replace('0x', '&#x')
26 new_dict[key_] = value
27
28 return new_dict

这样就得到了网页代码和实际字符额对应关系,如下:

'0xe06b': '天', '0xe0ce': '个', '0xe0d2': 'p', '0xe0d4': 'K', '0xe109': 's'

3.替换网页上的编码,提取正确的信息。

下面是全部源码:

  1 #coding=utf-8
2 #milo22233060@gmail.com
3 #2018/11/8 17:01
4 import requests
5 import re
6 from lxml import etree
7 import base64
8 import json
9 import pymysql
10 import time
11 from fontTools.ttLib import TTFont
12 def parse_ttf():
13 font_face = ""
14 b = base64.b64decode(font_face)
15 with open('shixi.ttf', 'wb') as f:
16 f.write(b)
17 #处理字体问题,返回字体对应的字典
18 def font_dict():
19 font = TTFont('shixi.ttf')
20 font.saveXML('shixi.xml')
21 ccmap = font['cmap'].getBestCmap()
22 print("ccmap:\n",ccmap)
23 newmap = {}
24 for key,value in ccmap.items():
25 # value = int(re.search(r'(\d+)', ccmap[key]).group(1)) - 1
26 #转换成十六进制
27 key = hex(key)
28 value = value.replace('uni','')
29 a = 'u'+'0' * (4-len(value))+value
30 newmap[key] = a
31 print("newmap:\n",newmap)
32 #删除第一个没用的元素
33 newmap.pop('0x78')
34 #加上前缀u变成unicode....
35 for i,j in newmap.items():
36 newmap[i] = eval("u" + "\'\\" + j + "\'")
37 print("newmap:\n",newmap)
38
39 new_dict = {}
40 #根据网页上显示的字符样式改变键值对的显示
41 for key, value in newmap.items():
42 key_ = key.replace('0x', '&#x')
43 new_dict[key_] = value
44
45 return new_dict
46
47 #开始爬取,替换字体
48 def crawl(url,new_dict):
49 headers = {
50 'User_Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
51 }
52 response = requests.get(url, headers=headers)
53 # print(response.text)
54 html = response.text
55 # print(new_dict)
56 #测试这个font-face是不是对的
57
58 for key,value in new_dict.items():
59 if key in html:
60 html = html.replace(key,value)
61 # print('yes')
62 else:
63 pass
64 # print('no')
65 # print(html)
66 html = etree.HTML(html)
67 result = html.xpath("//ul[@class='position-list']//li")
68
69 #获取职位名称,地址,公司名称,薪水,链接
70 result_data = []
71 for element in result:
72 data = {}
73 try:
74 link = 'https://www.shixiseng.com'+element.xpath(".//div[1]//div[1]//a/@href")[0]
75 position_name = element.xpath(".//div[1]//div[1]//a/text()")[0]
76 company_name = element.xpath(".//div[1]//div[2]//a/text()")[0]
77 location = element.xpath(".//div[2]//div[1]/text()")[0]
78 salary = element.xpath(".//div[2]//div[2]//span[1]/text()")[0]
79 week = element.xpath(".//div[2]//div[2]//span[2]/text()")[0]
80 month = element.xpath(".//div[2]//div[2]//span[3]/text()")[0]
81 except:
82 print('wrong!')
83 print(position_name,location,company_name,salary,link,week,month)
84 data['position_name'] = position_name
85 data['company_name'] = company_name
86 data['location'] = location
87 data['salary'] = salary
88 data['week'] = week
89 data['month'] = month
90 data['link'] = link
91 result_data.append(data)
92 print(result_data)
93 return result_data
94 if __name__ == '__main__':
95 url = 'https://www.shixiseng.com/interns?k=Python&p='
96 parse_ttf()
97 data = font_dict()
98 print(data)
99 result = []
100 for i in range(2):
101 result.extend(crawl(url+str(i+1),data))
102 print(result)

font-face会经常变化,这就需要及时更新这个数据。

欢迎指正。

python爬取实习僧招聘信息字体反爬的更多相关文章

  1. 用python抓取智联招聘信息并存入excel

    用python抓取智联招聘信息并存入excel tags:python 智联招聘导出excel 引言:前一阵子是人们俗称的金三银四,跳槽的小朋友很多,我觉得每个人都应该给自己做一下规划,根据自己的进步 ...

  2. 用Python爬取智联招聘信息做职业规划

    上学期在实验室发表时写了一个爬取智联招牌信息的爬虫. 操作流程大致分为:信息爬取——数据结构化——存入数据库——所需技能等分词统计——数据可视化 1.数据爬取 job = "通信工程师&qu ...

  3. python之scrapy爬取某集团招聘信息以及招聘详情

    1.定义爬取的字段items.py # -*- coding: utf-8 -*- # Define here the models for your scraped items # # See do ...

  4. python之crawlscrapy爬取某集团招聘信息以及招聘详情

    针对这种招聘信息,使用crawlscrapy很适合. 1.settings.py # -*- coding: utf-8 -*- # Scrapy settings for gosuncn proje ...

  5. node.js 89行爬虫爬取智联招聘信息

    写在前面的话, .......写个P,直接上效果图.附上源码地址  github/lonhon ok,正文开始,先列出用到的和require的东西: node.js,这个是必须的 request,然发 ...

  6. python爬虫---CrawlSpider实现的全站数据的爬取,分布式,增量式,所有的反爬机制

    CrawlSpider实现的全站数据的爬取 新建一个工程 cd 工程 创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com 连接提取器Link ...

  7. python爬虫爬取腾讯招聘信息 (静态爬虫)

    环境: windows7,python3.4 代码:(亲测可正常执行) import requests from bs4 import BeautifulSoup from math import c ...

  8. python之scrapy爬取某集团招聘信息

    1.创建工程 scrapy startproject gosuncn 2.创建项目 cd gosuncn scrapy genspider gaoxinxing gosuncn.zhiye.com 3 ...

  9. Python爬虫入门教程 64-100 反爬教科书级别的网站-汽车之家,字体反爬之二

    说说这个网站 汽车之家,反爬神一般的存在,字体反爬的鼻祖网站,这个网站的开发团队,一定擅长前端吧,2019年4月19日开始写这篇博客,不保证这个代码可以存活到月底,希望后来爬虫coder,继续和汽车之 ...

随机推荐

  1. Linux 软连接与硬连接 区别

    先说结论 软连接相当于快捷方式,访问软连接会被替换为其指向的绝对路径,如果其指向的文件被删除,则无法访问. 硬连接相当于指针,与它指向的文件都指向相同的inode,当其指向的文件被删除,inode由于 ...

  2. Spark SQL知识点大全与实战

    Spark SQL概述 1.什么是Spark SQL Spark SQL是Spark用于结构化数据(structured data)处理的Spark模块. 与基本的Spark RDD API不同,Sp ...

  3. [loj3146]路灯

    显然,能从$l$到$r$当且仅当$[l,r)$中的灯全部都亮,以下不妨令询问的$r$全部减1 当修改节点$x$时,找到包含$x$的极大的灯(除$x$以外)全部都亮的区间$[l,r]$,即令$l_{0} ...

  4. [bzoj1416]神奇的口袋

    容易发现操作任意次并不会改变每一个点的概率(因为每一个点加d的概率相同,期望与原数成比例),然后直接输出即可(要用高精度) 1 #include<bits/stdc++.h> 2 usin ...

  5. vue-if和show

    <template> <div> <div v-if="flag">今晚要上课</div> <div v-else> 今 ...

  6. Jenkins快速上手安装

    目录 环境准备 - JDK 安装 1. APT 安装 2. WAR包方式运行 3.Docker 方式运行 Jenkins 是一个独立的开源自动化服务器,可以用来自动化与构建.测试.交付或部署软件相关的 ...

  7. freeswitch APR库哈希表

    概述 freeswitch的核心源代码是基于apr库开发的,在不同的系统上有很好的移植性. 哈希表在开发中应用的非常广泛,主要场景是对查询效率要求较高的逻辑,是典型的空间换时间的数据结构实现. 大多数 ...

  8. 了解Threejs中的Clock对象以及简单应用

    什么是Clock对象 如果你对 JavaScript 有一定了解,那么 JavaScript 的时间对象 Date 你一定不陌生,Clock 本质上就是对 Date 进行封装,提供了一些方法和属性 当 ...

  9. ABC201题解

    因为学校的某些操作. 让最近两天的\(Atcoder\)都能打了,挺开心的. 想上次\(ABC\)看错题意,失败退场. ------------------------------ \(A\) 直接手 ...

  10. Codeforces 1422F - Boring Queries(树套树)

    upd on 2021.9.5:昨天的那个版本被 2-tower 卡爆了,故今天重发一个. Codeforces 题面传送门 & 洛谷题面传送门 没往"每个数最多只有一个 \(> ...