先贴爬虫程序下载地址:http://pan.baidu.com/s/1c2lxl1e
下载解压后 可直接运行 其中的 run.bat;或者你手动打开命令行执行:Joynet examples\SpiderZhihu.lua。
大家不妨先下载下来玩一玩(可以修改配置,在examples目录下的ZhihuConfig.lua,添加感兴趣的关键字)
这个爬虫程序作为我写的Lua网络库 Joynet 的示例。
主要使用了异步Connect/HTTP/HTTPS 访问知乎搜索页面,譬如 https://www.zhihu.com/search?type=content&q=test 就是搜索 test 相关的问题。
拿到它的response 采用字符串搜索其中的各个question的url 地址。然后进行访问。在拿到question的页面内容后查找其中的图片相关url地址,然后再访问图片服务器下载到本地。
整个爬虫的代码在:https://github.com/IronsDu/Joynet/blob/master/examples/SpiderZhihu.lua#L118。
一点问题:一般而言,开多个协程(链接)的话速度会提高很多。但在知乎爬虫中(访问知乎)并没有体现,反而更慢。我猜测与同时开多个链接到知乎时,知乎服务器做了速度限制。
(而且会给我返回部分 429 错误码···)
(我不知道该如何优化并发请求策略,以达到速度最快,且不会让服务器给我返回错误)
如果你无法访问github,可以看下面我复制过来的爬虫源码:
package.path = "./?.lua;./src/?.lua;./libs/?.lua;" local ZhihuConfig = require "examples.ZhihuConfig" local TcpService = require "TcpService" local HttpClient = require "HttpClient" local picTypes = {"png", "jpg", "jpeg"} local requestedPicNum = 0 local requestdPic = {} --当前已经发出请求的图片集合 local totalPicNum = 0 --当前已经完成请求的图片数量 local zhihuAddres = GetIPOfHost("www.zhihu.com") local picAddres = {} --pic http 服务器ip地址集合,key 为域名 UtilsCreateDir(ZhihuConfig.saveDir) local function singleCo(f) -- 不开启协程,因为经过测试发现,同时开多个链接到zhihu时,速度反而下降,通过访问百度进行对比,发现可能是zhihu服务器(故意)设置锁导致的 if false then coroutine_start(function () f() end) else f() end end -- 访问图片地址,下载成功则保存到文件 local function requestPic(clientService, pic_url, dirname, qoffset) local s,e = string.find(pic_url, "https:%/%/") local _,hostEnd = string.find(pic_url, "%.com") local host = string.sub(pic_url, e+1, hostEnd) local url = string.sub(pic_url, hostEnd+1, string.len(pic_url)) print(os.date().." start request :"..pic_url) if picAddres[host] == nil then picAddres[host] = GetIPOfHost(host) end local response = HttpClient.Request(clientService, picAddres[host], 443, true, "GET", url, host) if response ~= nil then local f = io.open(ZhihuConfig.saveDir.."\\"..dirname.."\\"..qoffset.."\\"..string.sub(url, 2, string.len(url)), "w+b") f:write(response) f:flush() f:close() f=nil print(os.date().." recv pic :"..pic_url.." success") totalPicNum = totalPicNum + 1 else print(os.date().." recv pic :"..pic_url.." failed") end end -- 访问问题页面 local function requestQuestion(clientService, question_url, dirname, qoffset) UtilsCreateDir(ZhihuConfig.saveDir.."\\"..dirname) UtilsCreateDir(ZhihuConfig.saveDir.."\\"..dirname.."\\"..qoffset) local fname = ZhihuConfig.saveDir.."\\"..dirname.."\\".."questions_address.txt" print(fname) local f = io.open(fname, "a+") f:write(question_url.."\r\n") f:flush() f:close() f=nil local response = HttpClient.Request(clientService, zhihuAddres, 443, true, "GET", question_url, "www.zhihu.com") if response ~= nil then for _,picType in ipairs(picTypes) do local pos = 1 while true do --TODO (优化匹配代码以及图片后缀) --查找此问题页面中的图片地址 local s, e = string.find(response, "https:%/%/pic%d.zhimg.com%/%w*%_r%."..picType, pos) if s ~= nil then local pic_url = string.sub(response, s, e) if not requestdPic[pic_url] then requestdPic[pic_url] = true requestedPicNum = requestedPicNum + 1 singleCo(function () --访问图片 requestPic(clientService, pic_url, dirname, qoffset) end) end pos = e else print("no more pic in question "..question_url) break end end end end end local function urlEnCode(w) local pattern="[^%w%d%._%-%* ]" s=string.gsub(w,pattern,function(c) local c=string.format("%%%02X",string.byte(c)) return c end) s=string.gsub(s," ","+") return s end local isAllCompleted = false function userMain() local clientService = TcpService:New() clientService:createService() coroutine_start(function() -- 访问知乎搜索页面,搜索配置的关键字的相关问题 for k,v in pairs(ZhihuConfig.querys) do for i=1,v.count do local response = HttpClient.Request(clientService, zhihuAddres, 80, false, "GET", "/search", "www.zhihu.com", {type="content",q=urlEnCode(v.q), offset=v.startOffset+10*(i-1)}) local pos = 1 if response ~= nil then while true do --查找问题页面地址 local s, e = string.find(response, "\"%/question%/%d*\"", pos) if s ~= nil then pos = e local question_url = string.sub(response, s+1 , e-1) print("request question_url :"..question_url) singleCo(function () --访问问题页面 requestQuestion(clientService, question_url, v.dirname, v.startOffset+10*(i-1)) end) else print("no more question, will break") break end end end end end isAllCompleted = true end) coroutine_start(function () while true do coroutine_sleep(coroutine_running(), 1000) print("Current Completed Pic Num : "..totalPicNum) print("Current requested pic num: "..requestedPicNum) if isAllCompleted then print("all pic completed, you can close process") break end end end) end coroutine_start(function () userMain() end) while true do CoreDD:loop() while coroutine_pengdingnum() > 0 do coroutine_schedule() end end
Joynet示例:知乎爬虫(搜索关键字相关回答,并下载其中的---图(mei)片(nv))的更多相关文章
-
C#分析搜索引擎URL得到搜索关键字,并判断页面停留时间以及来源页面
前台代码: var start; var end; var state; var lasturl = document.referrer; start = new Date($.ajax({ asyn ...
-
C# 分析搜索引擎url 得到搜索关键字
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
-
java使用itex读取pdf,并搜索关键字,为其盖章
导读:近期要做一个根据关键字定位pdf的盖章位置的相关需求,其中关键字可配置多个(包含pdf文档中可能不存在的关键字),当页面显示盖章完成时,打开pdf显示已经损坏. 排查后发现,当itext搜索的关 ...
-
Java爬虫搜索原理实现
permike 原文 Java爬虫搜索原理实现 没事做,又研究了一下爬虫搜索,两三天时间总算是把原理闹的差不多了,基本实现了爬虫搜索的原理,本次实现还是俩程序,分别是按广度优先和深度优先完成的,广度优 ...
-
在 Angular 中实现搜索关键字高亮
在 Angular 中,我们不应该试图直接修改 DOM 的内容,当需要更新 DOM 内容的时候,应该修改的其实是我们的数据模型,也就是 $scope 中的数据,Angular 会帮助我们将修改之后的数 ...
-
仿百度壁纸客户端(五)——实现搜索动画GestureDetector手势识别,动态更新搜索关键字
仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Frag ...
-
google 搜索关键字技巧
google 搜索关键字技巧 来源 https://www.cnblogs.com/qiudabai/articles/9143328.html inurl: 用于搜索网页上包含的URL. 这个语法 ...
-
帝国cms搜索关键字调用标签(showsearch)怎么用
前面ytkah介绍了如何让帝国CMS7.2搜索模板支持动态标签调用,现在我们来说说怎么调用帝国cms搜索关键字调用标签(showsearch).在帝国cms后台那边的使用方法:[showsearch] ...
-
如何给wp(Windows phone)中搜索关键字加亮?
问题来源 最近在群里看到群友讨论在wp中有个搜索功能,要求搜索关键字在搜索结果内容中加亮(即加颜色),由于wp中没有自带这样的控件,于是大家各抒自见,有人说用第三方控件,有人说用richtextbox ...
随机推荐
-
面试中常用的__proto__,prototype和原型链,你都了解了吗?
上一篇随笔主要讲了变量提升的问题,今天我们来讲讲很多前端er在初期很长一段时间内都没有完全搞明白的原型链和构造函数. 1,什么是构造函数 那么要讲到构造函数,必须要有一个函数,所以我们建立一个函数 f ...
-
squid安装配置
Squid做反向代理(192.168.1.69) squid.conf http_port 80 vhost vport visible_hostname pdd2.matrixcdn.net cac ...
-
OpenCV2学习笔记03:Qt中配置OpenCV环境
在Qt中开发基于OpenCV的应用时,需要配置对应函数库到环境变量,这时候我们需要使用到qmake能够识别的变量来指定环境变量. INCLUDEPATH: 用于指定搜索头文件到文件夹路径. LIBS: ...
-
利用CSP探测网站登陆状态
0x00 背景 今天看到zone里有同学发帖说了探测支付宝登录状态的帖子:http://zone.wooyun.org/content/17665 由此我想到了我们parsec的@/fd 半年前提到的 ...
-
zoj2760(最大流)
传送门:How Many Shortest Path 题意:给出n个点,和n*n的矩阵表示有向图.a[i][j]为-1表示i到j没有路径:不为-1则表示i到j的路径长度.给出一个vs和vt,要求vs到 ...
-
Create Table DDL sample(TSQL)
IF EXISTS (SELECT 1 FROM sysobjects o, sysusers u WHERE o.uid=u.uid AND o.name = 'Table_Name' AND u. ...
-
spring学习起步
1.搭载环境 去spring官网下载这几个包,其中commons-logging-1.2.jar是一个日志包,是spring所依赖的包,可以到apache官网上下载 也可以访问http://downl ...
-
第1回-使用ThinkPHP的3.1.3版本轻松建网站
使用ThinkPHP的3.1.3版本轻松建网站 首先,从ThinkPHP官网下载一个ThinkPHP3.1.3版本框架包. 其次,取出ThinkPHP3.1.3包中的核心部分,部署你的服务器项目下. ...
-
js中的Hook
1. 简单理解: hook(钩子)就是: 把将要执行的的函数或者一系列动作注册到一个统一的接口下面, 当应用程序调用此接口(即hook)时,就等于调用了这一系列动作.
-
Vue探索历程(一)
使用vue.js原文介绍:Vue.js是一个构建数据驱动的web界面库.Vue.js的目标是通过尽可能简单的API实现响应式数据绑定和组合的视图组件.vue.js上手非常简单,先看看几个例子: 例一: ...