网页爬虫抓取百度图片(一张前端与反爬虫这一的区别)

优采云 发布时间: 2022-02-06 21:23

  网页爬虫抓取百度图片(一张前端与反爬虫这一的区别)

  [目录]

  1. 前言

  对于一个网页,我们往往希望它结构合理,内容清晰,以便搜索引擎能够准确识别。另一方面,还有一些我们不希望内容被轻易获取的场景,比如电商的交易量网站、教育话题网站等。因为这些内容往往是产品的命脉,必须得到有效保护。这就是爬行动物和反爬行动物的话题的由来。爬取图片的整体操作流程可以分为三个步骤:

  获取页面信息 读取图片链接并将图片保存在本地指定目录

  2. 常见的反爬虫策略

  但是世界上没有可以完美反爬虫的网站。

  如果页面想要在不给爬虫机会的情况下正常显示在用户面前,它必须能够识别真人和机器人。因此,工程师们进行了各种尝试。这些策略大多用在后端,也是目前比较常规有效的手段,比如:

  而爬行动物可以无限接近真人,比如:

  所以我们说,100% 反爬策略?不存在的。这更像是一种体力活动,这是一个困难的问题。

  不过作为前端工程师,我们可以增加游戏的难度,设计一些非常(sang)有意义(bing)思维(kuang)**的反爬虫策略。

  3.前端和反爬虫3.1 FONT-FACE拼凑

  示例:猫眼电影

  在猫眼电影中,票房数据并不是纯粹的数字。页面使用font-face定义字符集,使用unicode映射显示。也就是说,除了图像识别,还要同时爬取字符集才能识别数字。

  而且,每次页面刷新,字符集的url都会发生变化,这无疑增加了爬取成本,难度更大。

  3.2 背景拼凑

  例子:

  与字体的策略类似,美团使用背景拼凑。数字实际上是图片,根据不同的背景偏移量显示不同的字符。

  而不同的页面,图片的字符排序也不同。但是理论上只需要生成0-9和一个小数点,所以不明白为什么会有重复的字符。

  3.3 个字符穿插

  示例:微信公众号文章

  一些微信公众号的文章中穿插着各种神秘的人物,这些人物都是通过样式隐藏起来的。这种方法虽然令人震惊……但其实识别过滤也不是太难,甚至可以做得更好,但也是一种脑洞。

  3.4 伪元素隐藏

  示例:汽车主页

  汽车之家,关键制造商信息被放入伪元素的内容中。这也是一种思路:爬取网页,必须解析CSS,获取伪元素的内容,增加了爬虫的难度。

  3.5 元素定位叠加

  示例:去哪里

  数学爱好者在哪里?对于一个4位数的票价,先用四个i标签渲染,然后用两个b标签进行绝对定位偏移,覆盖故意显示错误的i标签,最后在视觉上形成正确的价格……

  这说明爬虫无法解析CSS,必须做数学题。

  3.6 IFRAME 异步加载

  例子:

  打开网易云音乐页面时,html源码中几乎只有一个iframe,其src为空:about:blank。然后js开始运行,整个页面的frame异步塞进iframe中……

  不过这种方式带来的难度并不大,只是在异步和iframe处理上走了弯路(或者还有其他原因,不完全基于反爬的考虑),不管你用selenium还是phantom,都有API可用于 iframe 中的内容信息。

  3.7 个字符分割

  示例:全网代理IP

  在一些显示代理IP信息的页面上,IP的保护也很麻烦。

  他们会先将 IP 号和符号划分为 dom 节点,然后在中间插入混淆数字。如果爬虫不知道这个策略,就会认为自己成功获取了值;但如果爬虫注意到,它就会被解决。.

  3.8 个字符集替换

  示例:去哪里移动边

  移动版去哪儿也会欺骗爬虫。

  3211明明写在html里,但是1233是直观显示的。原来他们重新定义了字符集,3和1的顺序刚好互换了结果……

  4.示例:爬取百度图库

  import re

import os

import time

import requests

# from selenium import webdriver

#########################

###此段代码不需要关心啥意思###

#########################

if not os.path.exists('百度图片'):

os.mkdir('百度图片')

#####################

###限制30张图片的代码###

####################

# 获取所有图片

response = requests.get(

'http://image.baidu.com/search/index?ct=201326592&cl=2&st=-1&lm=-1&nc=1&ie=utf-8&tn=baiduimage&ipn=r&rps=1&pv=&fm=rs7&word=风景')

data = response.text

img_desc_dics = re.findall("app.setData(\('imgData.*?\));", data, re.S)[0]

img_desc_dics = eval(str(img_desc_dics))

# 获取所有图片的数据

img_datas = img_desc_dics[1]['data']

count = 0

for img_data in img_datas:

# 获取搜索图片的参数

os_ = img_data.get('os')

cs_ = img_data.get('cs')

if os_ and cs_:

# 获取搜索图片的信息

img_search_url = f'http://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E9%A3%8E%E6%99%AF&step_word=&hs=0&pn=1&spn=0&di=195030&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=-1&cs={cs_}&os={os_}'

img_search_response = requests.get(img_search_url)

img_search_data = img_search_response.text

# 获取图片信息

img_url = re.findall('''\('firstSc'\);" src="(.*?)"''', img_search_data)[0]

img_name = img_url.split('/')[-1]

img_name = os.path.join('百度图片', img_name) # 拼接出图片的地址,如 百度图片/3822951_144045377000_2.jpg

# 保存图片

img_response = requests.get(img_url)

img_data = img_response.content

fw = open(img_name, 'wb')

fw.write(img_data)

fw.flush()

# 提示

count += 1

print(f'{img_name}保存成功,成功保存{count}张')

# 防止百度禁ip,慢一点

time.sleep(0.01)

  

  #########################################################################

###自行百度selenium的用法,使用这一套代码可以无限爬取所有图片,否则将被限制30张###

## 记得加库哦

########################################################################

page_count_end = 2 # 爬取 指定数字(10)* 30 = 300张图片

chrome = webdriver.Chrome()

## 安装谷歌插件

##http://chromedriver.storage.googleapis.com/index.html?tdsourcetag=s_pcqq_aiomsg

## 查看你电脑的谷歌版本,寻找对应版本进行下载解压

try:

chrome.implicitly_wait(10)

chrome.get(

'http://image.baidu.com/search/index?ct=201326592&cl=2&st=-1&lm=-1&nc=1&ie=utf-8&tn=baiduimage&ipn=r&rps=1&pv=&fm=rs7&word=风景')

js_code = '''

window.scrollTo(0, document.body.scrollHeight);

var lenOfPage = document.body.scrollHeight;

return lenOfPage

'''

# selenium控制爬取页数

count = 0

page_count = 0

while page_count < page_count_end:

try:

page_count += 1

chrome.execute_script(js_code)

time.sleep(0.3)

except:

continue

img_desc_search_urls = re.findall(&#39;href="(/search/detail\?.*?)"&#39;, chrome.page_source, re.S) # re.S使.可以匹配换行符

# 获取所有图片的数据

for img_data in img_desc_search_urls:

try:

# 获取搜索图片的参数

os_ = re.findall(&#39;os=(.*?)&amp;&#39;, img_data)[0]

cs_ = re.findall(&#39;cs=(.*?)&amp;&#39;, img_data)[0]

if os_ and cs_:

# 获取搜索图片的信息

img_search_url = f&#39;http://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E9%A3%8E%E6%99%AF&step_word=&hs=0&pn=1&spn=0&di=195030&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=-1&cs={cs_}&os={os_}&#39;

img_search_response = requests.get(img_search_url)

img_search_data = img_search_response.text

# 获取图片信息

img_url = re.findall(&#39;&#39;&#39;\(&#39;firstSc&#39;\);" src="(.*?)"&#39;&#39;&#39;, img_search_data)[0]

img_name = img_url.split(&#39;/&#39;)[-1]

img_name = os.path.join(&#39;百度图片&#39;, img_name) # 拼接出图片的地址,如 百度图片/3822951_144045377000_2.jpg

# 保存图片

img_response = requests.get(img_url)

img_data = img_response.content

fw = open(img_name, &#39;wb&#39;)

fw.write(img_data)

fw.flush()

# 提示

count += 1

print(f&#39;{img_name}保存成功,成功保存{count}张&#39;)

# 防止百度禁ip,慢一点

time.sleep(0.01)

except:

continue

except Exception:

pass

finally:

chrome.close()

  结果

  

  

  由于百度的反爬措施是不断更新的,如果过了一段时间还想爬,就需要寻找新的规则

  5.总结

  对于每个 网站 爬行,都有一定的规则。每一个网站,尤其是大的网站,都在定期排版。做爬虫,必须注意细节,慎重决策。对于成败,找到你需要的文字、图片,或者视频、文件等,找到它们的链接,进行多重分析,耐心找出规律,这是你成功的关键。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线