show | version | enable_checker |
---|---|---|
step |
1.0 |
true |
- 上次爬了纸飞机的网站
- 从首页爬到内容页
- 从内容页第一个示例图开始
- 一个个地遍历
- 经过二重循环完成任务
- 到最后才发现图像的普遍性规律
- 不过有的网站中的图片是嵌入到网页中的
- 这种情况怎么办呢?🤔
- img 元素的 src 属性
- div 元素的 style 属性中的 background-image 属性
- url 后面所跟的图片来自于 data
- 这些图片怎么能就直接写在网页里面呢?
- 这种写法最初的征求意见稿来自于 rfc2397
- 那么,什么是 rfc 呢?
- Internet 技术管理的核心是制定网络连接和应用的协议标准。在 Internet 上,任何一个用户都可以对 Internet 某一领域的问题提出自己的解决方案或规范,作为 Internet 草案(ID,Internet Drafts)提交给 IETF。
- 草案存放在美国、欧洲和亚太地区的工作文件站点上,供世界多国自愿参加的 IETF 成员进行讨论、测试和审查。最后由 IESG 确定该草案是否能成为 Internet 的标准。
- RFC 文档也称请求审议文档(Requests for Comments,RFC),是一系列不断修改和完善的报告、协议提案和协议标准,是用于发布 Internet 标准的一种网络文件或工作报告,篇幅从 1 页到数百页不等。
- RFC 文档必须被分配 RFC 编号后才能在网络上发布。例如,RFC 2401 的内容是有关 Internet 协议的安全体系结构。
- 如果一个提议规范进行了修改,并且对 Internet 草案进行了重写和升级,则在发布时将获得一个新的 RFC 编号(该编号的数字大于原来的编号)。
- 因此,通过 RFC 编号,人们可以确定哪些是最新的文档。
- 就算可以把图片数据直接写在网页里,这么做有什么好处呢?
- 这样做的好处是:
- 节省了一个 http 请求
- 原来浏览器读到 img 的时候
- 需要给图片地址再发个请求
- 这样就要再去请求得到图片的地址
- 这样做的坏处:
- 浏览器不会缓存图片的数据
- 每次都要真的请求
- 不会从缓存中读取数据
- 而且一般来说写在 data 中的数据量稍微大些
- 为什么会变大呢?
- Base64 是网络上最常见的用于传输 8Bit 字节代码的编码方式之一,大家可以查看 RFC2045 ~ RFC2049,上面有 MIME 的详细规范
- Base64 编码可用于在 HTTP 环境下传递较长的标识信息
- Base64 要求把每三个 8Bit 的字节转换为四个 6Bit 的字节(3 * 8 = 4 * 6 = 24)
- 然后把 6Bit 再添两位高位 0,组成四个 8Bit 的字节
- 也就是说,转换后的字符串理论上将要比原来的长 1/3
- 这里说的是把原始信息转化为 base64 之后会增长
- 不过原始信息格式也很多啊
- data:,文本数据
- data:text/plain,文本数据
- data:text/html,HTML 代码
- data:text/html;base64,base64 编码的 HTML 代码
- data:text/css,CSS 代码
- data:text/css;base64,base64 编码的 CSS 代码
- data:text/javascript,Javascript 代码
- data:text/javascript;base64,base64 编码的 Javascript 代码
- data:image/gif;base64,base64 编码的 gif 图片数据
- data:image/png;base64,base64 编码的 png 图片数据
- data:image/jpeg;base64,base64 编码的 jpeg 图片数据
- data:image/x-icon;base64,base64 编码的 icon 图片数据
- 真的有网站用这种 data 格式存储照片么?
- 这个网站叫做汉字源
- 是汉字叔叔做的
- 不过现在日期停留在 2017
- 我们去观察一下 robots.txt
- 并没有禁止什么
- 那么我们可以走起来了
- 这是一个 Post 请求
- 而不是我们以前见到的 Get 请求
- 而且特别不起眼的是消息头里面多了两个 key-value 对
- Chinese
- Seal
- Chinese
- 应该是所请求的文字的 unicode 编码对应的十进制形式
- Seal
- 不随请求文字变化而变化
- 可以看做是固定值
from requests import post
from lxml import etree
import os
import time
char = 0x4e00
print(char)
url = "https://hanziyuan.net/etymology"
data = {
"chinese": chr(char),
"Bronze": "CfDJ8J6z8luTOtZGq022DWMpS8797u7UDVKSjSpbmdg-dyOCD88NgYd5tPIVv0KVNMh2sz1e_3xpmaXZCvl7pWgwiFOtY03F6TIUUh_dQ6d9NOF77qrA2Rt1eDdCKl5FraMguKOKMmUuWI-wg-hmbU1chKg"
}
headers = {
"Host": "hanziyuan.net",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:93.0) Gecko/20100101 Firefox/93.0",
"Accept": "text/html, */*; q=0.01",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Chinese": "26377",
"Seal": "CfDJ8J6z8luTOtZGq022DWMpS8797u7UDVKSjSpbmdg-dyOCD88NgYd5tPIVv0KVNMh2sz1e_3xpmaXZCvl7pWgwiFOtY03F6TIUUh_dQ6d9NOF77qrA2Rt1eDdCKl5FraMguKOKMmUuWI-wg-hmbU1chKg",
"X-Requested-With": "XMLHttpRequest",
"Content-Length": "180",
"Origin": "https://hanziyuan.net",
"Connection": "keep-alive",
"Referer": "https://hanziyuan.net/",
"Cookie": "Oracle=CfDJ8J6z8luTOtZGq022DWM...",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin"
}
headers['Chinese'] = str(char)
response = post(url=url, data=data, headers=headers,)
print(response)
- 这样确实可以得到响应
- 得到了响应之后又该如何呢?
- 这个图片其实是写在 css 的 background 中的
- 而且用的就是 data 这种写法
- 是把 svg+xml 文件转化为了 data 形式
- 那我们首先要拿到 style 的位置
et_html = etree.HTML(response.content)
et_style = et_html.xpath("//body//style")
text = et_style[0].text
svglist = re.split("#\w{1,7}, #etymology\w{1,7} \{ background-image: url\(\'",text)
i = 0
html = ""
for svg in svglist:
html += "<img src=\"" + svg + " \" />"
i += 1
with open(chr(char),"wt") as f:
f.write(html)
- 找到 style 的位置然后把整个 style 文本进行切分
- 切分为 svgdata 的 list
- 然后对于每个 svgdata 写一个 img 元素
- 追加进入这个文字对应的 html 文件中
- 最后可对于每个确定的文字可以得到他的 html
import re,base64
from requests import post
from lxml import etree
import os
import time
for char in range(0x4e00,0x9FFF):
try:
print(char)
url = "https://hanziyuan.net/etymology"
data = {
"chinese": chr(char),
"Bronze": "CfDJ8J6z8luTOtZGq022DWMpS8797u7UDVKSjSpbmdg-dyOCD88NgYd5tPIVv0KVNMh2sz1e_3xpmaXZCvl7pWgwiFOtY03F6TIUUh_dQ6d9NOF77qrA2Rt1eDdCKl5FraMguKOKMmUuWI-wg-hmbU1chKg"
}
headers = {
"Host": "hanziyuan.net",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:93.0) Gecko/20100101 Firefox/93.0",
"Accept": "text/html, */*; q=0.01",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Chinese": "26377",
"Seal": "CfDJ8J6z8luTOtZGq022DWMpS8797u7UDVKSjSpbmdg-dyOCD88NgYd5tPIVv0KVNMh2sz1e_3xpmaXZCvl7pWgwiFOtY03F6TIUUh_dQ6d9NOF77qrA2Rt1eDdCKl5FraMguKOKMmUuWI-wg-hmbU1chKg",
"X-Requested-With": "XMLHttpRequest",
"Content-Length": "180",
"Origin": "https://hanziyuan.net",
"Connection": "keep-alive",
"Referer": "https://hanziyuan.net/",
"Cookie": "Oracle=CfDJ8J6z8...",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin"
}
headers['Chinese'] = str(char)
response = post(url=url, data=data, headers=headers,)
print(response)
et_html = etree.HTML(response.content)
et_style = et_html.xpath("//body//style")
text = et_style[0].text
svglist = re.split("#\w{1,7}, #etymology\w{1,7} \{ background-image: url\(\'",text)
i = 0
html = ""
#print(type(svglist),len(svglist))
for svg in svglist:
html += "<img src=\"" + svg + " \" />"
i += 1
with open(chr(char),"wt") as f:
f.write(html)
char += 1
except:
print("\033[41m[error]\033[0m char is " + str(char))
- 这确实可以爬取出来
- 但是好像少了分类
- 如果像原来那样有分类就更好了
- 我要利用原来网页里的结构
- 不要把他零碎取出来再组装
- 我就直接把它取出来
- 整体性地取出来
import requests
inputchar = '收'
styss = '''
<link href="https://hanziyuan.net/css/bootstrap.min.css" rel="stylesheet"><link href="https://hanziyuan.net/css/bootstrap-theme.min.css" rel="stylesheet"><style>@-ms-viewport{width:device-width}@-o-viewport{width:device-width}@viewport{width:device-width}@keyframes ladda-spinner-line-fade{0%,to{opacity:.22}1%{opacity:1}}.ladda-button{position:relative}.ladda-button .ladda-spinner{position:absolute;z-index:2;display:inline-block;width:32px;top:50%;margin-top:0;opacity:0;pointer-events:none}.ladda-button .ladda-label{position:relative;z-index:3}.ladda-button .ladda-progress{position:absolute;width:0;height:100%;left:0;top:0;background:rgba(0,0,0,.2);display:none;transition:all .1s linear!important}.ladda-button[data-loading] .ladda-progress{display:block}.ladda-button,.ladda-button .ladda-label,.ladda-button .ladda-spinner{transition:all .3s cubic-bezier(.175,.885,.32,1.275)!important}.ladda-button[data-style=zoom-in],.ladda-button[data-style=zoom-in] .ladda-label,.ladda-button[data-style=zoom-in] .ladda-spinner,.ladda-button[data-style=zoom-out],.ladda-button[data-style=zoom-out] .ladda-label,.ladda-button[data-style=zoom-out] .ladda-spinner{transition:all .3s ease!important}.ladda-button[data-style=expand-right] .ladda-spinner{right:-6px}.ladda-button[data-style=expand-right][data-size=s] .ladda-spinner,.ladda-button[data-style=expand-right][data-size=xs] .ladda-spinner{right:-12px}.ladda-button[data-style=expand-right][data-loading]{padding-right:56px}.ladda-button[data-style=expand-right][data-loading] .ladda-spinner{opacity:1}.ladda-button[data-style=expand-right][data-loading][data-size=s],.ladda-button[data-style=expand-right][data-loading][data-size=xs]{padding-right:40px}.ladda-button[data-style=expand-left] .ladda-spinner{left:26px}.ladda-button[data-style=expand-left][data-size=s] .ladda-spinner,.ladda-button[data-style=expand-left][data-size=xs] .ladda-spinner{left:4px}.ladda-button[data-style=expand-left][data-loading]{padding-left:56px}.ladda-button[data-style=expand-left][data-loading] .ladda-spinner{opacity:1}.ladda-button[data-style=expand-left][data-loading][data-size=s],.ladda-button[data-style=expand-left][data-loading][data-size=xs]{padding-left:40px}.ladda-button[data-style=expand-up]{overflow:hidden}.ladda-button[data-style=expand-up] .ladda-spinner{top:-32px;left:50%;margin-left:0}.ladda-button[data-style=expand-up][data-loading]{padding-top:54px}.ladda-button[data-style=expand-up][data-loading] .ladda-spinner{opacity:1;top:26px;margin-top:0}.ladda-button[data-style=expand-up][data-loading][data-size=s],.ladda-button[data-style=expand-up][data-loading][data-size=xs]{padding-top:32px}.ladda-button[data-style=expand-up][data-loading][data-size=s] .ladda-spinner,.ladda-button[data-style=expand-up][data-loading][data-size=xs] .ladda-spinner{top:4px}.ladda-button[data-style=expand-down]{overflow:hidden}.ladda-button[data-style=expand-down] .ladda-spinner{top:62px;left:50%;margin-left:0}.ladda-button[data-style=expand-down][data-size=s] .ladda-spinner,.ladda-button[data-style=expand-down][data-size=xs] .ladda-spinner{top:40px}.ladda-button[data-style=expand-down][data-loading]{padding-bottom:54px}.ladda-button[data-style=expand-down][data-loading] .ladda-spinner{opacity:1}.ladda-button[data-style=expand-down][data-loading][data-size=s],.ladda-button[data-style=expand-down][data-loading][data-size=xs]{padding-bottom:32px}.ladda-button[data-style=slide-left]{overflow:hidden}.ladda-button[data-style=slide-left] .ladda-label{position:relative}.ladda-button[data-style=slide-left] .ladda-spinner{left:100%;margin-left:0}.ladda-button[data-style=slide-left][data-loading] .ladda-label{opacity:0;left:-100%}.ladda-button[data-style=slide-left][data-loading] .ladda-spinner{opacity:1;left:50%}.ladda-button[data-style=slide-right]{overflow:hidden}.ladda-button[data-style=slide-right] .ladda-label{position:relative}.ladda-button[data-style=slide-right] .ladda-spinner{right:100%;margin-left:0;left:16px}[dir=rtl] .ladda-button[data-style=slide-right] .ladda-spinner{right:auto}.ladda-button[data-style=slide-right][data-loading] .ladda-label{opacity:0;left:100%}.ladda-button[data-style=slide-right][data-loading] .ladda-spinner{opacity:1;left:50%}.ladda-button[data-style=slide-up]{overflow:hidden}.ladda-button[data-style=slide-up] .ladda-label{position:relative}.ladda-button[data-style=slide-up] .ladda-spinner{left:50%;margin-left:0;margin-top:1em}.ladda-button[data-style=slide-up][data-loading] .ladda-label{opacity:0;top:-1em}.ladda-button[data-style=slide-up][data-loading] .ladda-spinner{opacity:1;margin-top:0}.ladda-button[data-style=slide-down]{overflow:hidden}.ladda-button[data-style=slide-down] .ladda-label{position:relative}.ladda-button[data-style=slide-down] .ladda-spinner{left:50%;margin-left:0;margin-top:-2em}.ladda-button[data-style=slide-down][data-loading] .ladda-label{opacity:0;top:1em}.ladda-button[data-style=slide-down][data-loading] .ladda-spinner{opacity:1;margin-top:0}.ladda-button[data-style=zoom-out]{overflow:hidden}.ladda-button[data-style=zoom-out] .ladda-spinner{left:50%;margin-left:32px;transform:scale(2.5)}.ladda-button[data-style=zoom-out] .ladda-label{position:relative;display:inline-block}.ladda-button[data-style=zoom-out][data-loading] .ladda-label{opacity:0;transform:scale(.5)}.ladda-button[data-style=zoom-out][data-loading] .ladda-spinner{opacity:1;margin-left:0;transform:none}.ladda-button[data-style=zoom-in]{overflow:hidden}.ladda-button[data-style=zoom-in] .ladda-spinner{left:50%;margin-left:-16px;transform:scale(.2)}.ladda-button[data-style=zoom-in] .ladda-label{position:relative;display:inline-block}.ladda-button[data-style=zoom-in][data-loading] .ladda-label{opacity:0;transform:scale(2.2)}.ladda-button[data-style=zoom-in][data-loading] .ladda-spinner{opacity:1;margin-left:0;transform:none}.ladda-button[data-style=contract]{overflow:hidden;width:100px}.ladda-button[data-style=contract] .ladda-spinner{left:50%;margin-left:0}.ladda-button[data-style=contract][data-loading]{border-radius:50%;width:52px}.ladda-button[data-style=contract][data-loading] .ladda-label{opacity:0}.ladda-button[data-style=contract][data-loading] .ladda-spinner{opacity:1}.ladda-button[data-style=contract-overlay]{overflow:hidden;width:100px;box-shadow:0 0 0 2000px transparent}.ladda-button[data-style=contract-overlay] .ladda-spinner{left:50%;margin-left:0}.ladda-button[data-style=contract-overlay][data-loading]{border-radius:50%;width:52px;box-shadow:0 0 0 2000px rgba(0,0,0,.8)}.ladda-button[data-style=contract-overlay][data-loading] .ladda-label{opacity:0}.ladda-button[data-style=contract-overlay][data-loading] .ladda-spinner{opacity:1}[dir=rtl] .ladda-spinner>div{left:25%!important}.navbar-collapse{overflow:hidden}body{position:relative;padding-top:50px}.row-eq-height{overflow:hidden}.row-eq-height [class*=col-]{margin-bottom:-99999px;padding-bottom:99999px}.pre-inline{white-space:pre-line}.m-0{margin:0}.p-0{padding:0}.mx-0{margin-left:0;margin-right:0}.my-1{margin-top:15px;margin-bottom:15px}.px-0{padding-right:0;padding-left:0}.p-1{padding:15px}.px-1{padding-right:15px;padding-left:15px}.py-1{padding-bottom:15px}.pt-1,.py-1{padding-top:15px}.pb-1{padding-bottom:15px}.bg-purple{background-color:#563d7c}.bg-black{background-color:#000}.border-purple{border-color:#563d7c}.border-top{border-top:1px solid}.text-black{color:#000}.text-lg{font-size:50px}.text-danger-color{color:#f44}a.text-danger-color,a.text-danger-color:visited{color:#f44!important}a.text-danger-color:active,a.text-danger-color:hover{color:#ff9c9c!important}.text-white{color:#eee}a.text-white,a.text-white:active,a.text-white:hover,a.text-white:visited{color:#fff!important}@media (min-width:768px) and (max-width:991px){.navbar-collapse.collapse{display:none!important}.navbar-collapse.collapse.in,.navbar-header .collapse,.navbar-toggle{display:block!important}.navbar-header{float:none}}.etymology-news .media-left a{width:50px;height:64px;display:block;font-size:40px;color:#e1bee7}.etymology-videos .media-left a{width:114px;height:64px;display:block;background-size:cover;background-repeat:no-repeat;background-position:50% 50%}.etymology-brand{padding-left:0;padding-right:0}@media (min-width:768px){.etymology-brand{padding-left:15px;padding-right:15px}}@media (max-width:351px){.etymology-nav-icon{display:none}}.navbar-fixed-top .navbar-collapse{max-height:none}.etymology-search button{margin-bottom:10px}.etymology-stat div{padding:5px}.etymology-stat h3{margin-top:10px}.etymology-alert a{margin:5px 0}.etymology-result ul{margin-top:15px}.etymology-result ul li div{background-color:#fff;width:105px;height:70px;background-size:60px 60px;background-position:50% 50%;background-repeat:no-repeat;color:transparent;cursor:pointer}.etymology-result ul li button{margin-top:5px;margin-bottom:15px;width:105px;font-weight:700}.etymology-research a{font-weight:700}.etymology-news .media-body{color:#ccc}.etymology-news .media-heading{color:#fff}.modal-dialog{width:auto;margin-left:15px;margin-right:15px}.modal-content,.modal-dialog{height:95%}.modal-content{background-size:contain;background-repeat:no-repeat;background-position:50%}.modal-body,.modal-footer,.modal-header{border:0 none}.modal-body{height:calc(100% - 120px)}</style>
'''
headers = {
'Cookie': 'Oracle=CfDJ8J6z8...; Hm_lvt_44bf35035989ecd905587eb98a45525e=1635135381; Hm_lpvt_44bf35035989ecd905587eb98a45525e=1635135381; _ga=GA1.2.324463930.1635135381; _gid=GA1.2.537869903.1635135381',
'Host': 'hanziyuan.net',
'Origin': 'https://hanziyuan.net',
'Referer': 'https://hanziyuan.net/',
'Seal': 'CfDJ8J6z8luTOtZGq022DWMpS84Dbxx9YAbaEa87-Rk4j45RZtD1SMhhoZNcytqZXVG4EYBnX82ZnmulDMFwnL4qzb3euYEwfYBhi4_xvTX1FVFu_jL0IIqgnPhxPabW-spkhLDRJ81p0nlvV1XpYOrGc2M',
'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
'sec-ch-ua-mobile': '?0',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
data = {
'chinese': inputchar,
'Bronze': 'CfDJ8J6z8luTOtZGq022DWMpS84Dbxx9YAbaEa87-Rk4j45RZtD1SMhhoZNcytqZXVG4EYBnX82ZnmulDMFwnL4qzb3euYEwfYBhi4_xvTX1FVFu_jL0IIqgnPhxPabW-spkhLDRJ81p0nlvV1XpYOrGc2M'
}
url = 'https://hanziyuan.net/etymology'
headers['Chinese'] = str(ord(data['chinese']))
r = requests.post(url, data=data, headers=headers)
print(r.text, r.status_code)
print('---------------')
with open('test.html', 'w', encoding='utf-8')as f:
f.write(styss+'\n')
f.write(r.text)
print('---------------')
- 先把 head 里面的样式信息给都拿出来
- 然后把 body 里的所有信息都拿出来
- svg 的 data 就在 body 中的 style 里面
- 这样就把原来的网页结构拿到了
- 这次爬了汉字源
- 图片不只是可以单独存在
- 也可以嵌入到网页中的
- 应该注意到请求头里面可以放东西
- 爬取的时候可以利用原来网页整体的结构
- 图片爬完了
- 还能爬点什么呢?🤔
- 下次再说