爬虫常见的反爬策略与反爬攻克手段
反爬策略与解决策略
反爬策略1:通过UA限制或者其他头信息限制
解决方案:构建用户代理池(第2节糗百案例)或其他头信息
反爬策略2:通过访问者IP限制
解决方案:构建IP代理池
反爬策略3:通过验证码限制
解决方案:手工打码(第8节知乎案例)、验证码接口自动识别或者通过机器学习自动识别
反爬策略4:通过数据的异步加载限制
解决方案:抓包分析 (第7节淘宝爬虫案例)或者使用 PhantomJS
反爬策略5:通过Cookie限制
解决方案:进行Cookie处理(第8节知乎案例)
反爬策略6:通过 JS 限制(如请求的数据通过 JS 随机生成等)
解决方案:分析 JS 解密或者使用 PhantomJS (裁判文书网、腾讯动漫)
中国裁判文书网 爬取
中国裁判文书网通过 JS 生成访问页面的 URL
import execjs
# 加载 JS 文件
fh = open("./base64.js", 'r')
js1 = fh.read()
fh.close()
fh = open("./md5.js", 'r')
js2 = fh.read()
fh.close()
fh = open("./getkey.js", 'r')
js3 = fh.read()
fh.close()
js_all = js1 + js2 + js3
# ...
compile_js = execjs.compile(js_all)
vI5x = compile_js.call("getKey")
# ...
# 在头部中使用 vI5x 进行访问
使用 PhantomJS
import time
import re
from selenium import webdriver
browser = webdriver.PhantomJS()
browser.get("http://www.baidu.com")
a = browser.get_screenshot_as_file("./test.jpg")
browser.find_element_by_xpath('.//*[@id="kw"]').clear()
browser.find_element_by_xpath('.//*[@id="kw"]').send_keys("爬虫")
browser.find_element_by_xpath('.//*[@id="su"]').click()
time.sleep(5)
a = browser.get_screenshot_as_file("./test2.jpg")
data = browser.page_source
title = re.compile("<title>(.*?)</title>").findall(data)
brower.quit()
爬取腾讯漫画
def getCartoon(page):
from selenium import webdriver
import time
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import re
import urllib.request
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = ("Mozilla/4.0 (compatible; MSIE 5.5; windows NT)")
browser = webdriver.PhantomJS(desired_capabilities=dcap)
# 打开动漫的一页
browser,get ("http://ac.qq.com/ComicView/index/id/539443/cid/" +str (page))
for i in range (20):
js = 'window.scrollTo('+ str(1280) + ',' + str((1+1)*720) + ')'
browser.execute_script (js)
time.sieep(1)
# 将打开的界面截图保存,方便现察
a = browser.get_screenshot_as_file("./test. jpg")
# 获取当前页面所有源码(包含触发出来的异步加载的资源)
data = browser.page_source
fh=open("./test2.jpg","w",encoding="utf_8")
fh.write (data)
fh.close()
browser.quit ()
# 构造正则表达式提取动漫图片资源网址
pat = '<img src="(https:\/\/manhua.qpic.cn\/manhua_detail.*?. jpg\/0)"'
# 获取所有动漫图片资源网址
allid = re.compile(pat, re.S).findall(data)
for thisurl in allid:
print(thisurl)
for page in range(1, 10):
getCartoon(page)
分布式爬虫
自己实现
-
安装容器
-
修改配置,使 MySQL 和 Redis 支持远程连接
-
开启 MySQL 和 Redis
-
运行容器
-
编写爬虫程序
import redis import urllib # 连接 redis rconn = redis.Redis("ip", "port") for i in range(100): # 查询是否爬取过 isdo = rconn.hget("url", str(i)) if isdo != None: continue # 将爬取信息写入 redis rconn.hset("url", str(i), "1") data = urllib.request.urlopen("url").read().decode('utf-8'. 'ignore')
使用 Scrapy-redis 实现
在 settings.py 里进行配置
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True
REDIS_URL = "redis://ip:port"
其他小节笔记
阿里云爬虫项目课程笔记【1】:正则表达式 与 XPath表达式
阿里云爬虫项目课程笔记【2】:Urllib模块 与 糗事百科爬取实战
阿里云爬虫项目课程笔记【3】:腾讯视频评论实战
阿里云爬虫项目课程笔记【4】:Requests 模块 与 云栖社区博文爬虫实战
阿里云爬虫项目课程笔记【5】:Scrapy 模块 与 当当爬虫实战
阿里云爬虫项目课程笔记【6 - 8】:招聘信息、淘宝网商品信息 与 知乎 爬虫实战
1800

被折叠的 条评论
为什么被折叠?



