常见问题
1.网页采集器
1.1.自动嗅探失败
网页采集器具备自动嗅探功能,本质上是替换掉了底层的代理。因此,所有的请求都通过Hawk内部,自然就能根据需求筛选出所需的请求。
1.2.被封锁问题
被封锁有几个原因:
被网站识别为非浏览器
出现这种情况的原因是请求参数为空,没有模拟为浏览器(user-agent),如大众点评只防此类爬虫。
最新改进的版本中,Hawk默认请求参数已经加入了user-agent,因此能解决掉一大部分初级问题。
频繁访问
这取决于网站如何认定是同一个使用者。
- 有的网站认为同一台机器的不同浏览器也是不同的用户。
- 有的网站认为只要IP相同,则使用者一定相同
对前一种情况,可以随机在一大批User-agent列表中挑选一条,模拟为不同的浏览器,就能大大降低被PB的概率。典型的例子如豆瓣。
对后一种情况,很不幸需要使用真正的代理,或使用分布式方案。免费代理通常都不稳定,而付费代理则需要付费,很少有人愿意为了爬虫付钱(一脸黑线)。
因此,Hawk会考虑提供第一种情况的解决方案,但不会自动开启,而是在用户需要的时候手工开启。
而自动代理切换,目前Hawk不会提供支持。原因更多考虑的是技术之外的因素。
1.3.抓取动态请求
这是被问的最多的问题。加载一个完整的网页,可能需要几十次请求,不少请求是ajax和动态的,而不少数据都保存在这些请求之中。
最早版本的Hawk内置了一个IE内核的浏览器,后来取消了这个功能。原因很简单:
- 内置浏览器,导致过分复杂
- 无法多线程抓取
- 大量无用的请求,导致抓取速度变慢
- 即使内置浏览器,也不见得能抓取所有动态请求
因此,纯HttpClient能够精确并只抓取你想要的内容,只要正确构造它即可。 如何使用?你需要配置一个网页采集器。 将它的行为,模拟到和浏览器一致。
第一种方法,查看浏览器的请求,参考 ,将Http请求详情复制过来,注意选择GET和POST。
之后,将嗅探到的地址拷贝到网页采集器的URL输入框中,查看是否能正确获取内容。 如果是POST请求,就更复杂一些。在数据清洗模块中,网页采集器拖入的列需要是对应的URL,你还需要构造出每次访问的post数据,单独作为一列。在网页采集器中如下配置:
注意列名需要用方括号括起来,否则每次POST数据都会是所填的数据。
1.4.验证码问题
这也是问的非常多的问题,很不幸,不支持。验证码各种各样,简单到纯数字,复杂到12306,图像转文本涉及到太多的不确定因素。
解决方案也有,一些网站提供识别验证码的接口API,因此你可以让Hawk去模拟网站的API,将图片地址传递过去,API会自动返回验证码。坏消息是这个一般需要收费。 不过,能配置Hawk去做这样的请求的人,一定也能够写Python了,算了,他还是去写Python吧,别跳Hawk这个坑了。
1.5.Path搜索相关问题
网页采集器中,填写关键字,却发现无法找到XPath。 可能的原因:
网页是动态网页
因此本链接不包含该关键字,建议考虑使用嗅探方案
关键字太长
是文本中包含不可见字符时经常出现。例如 340[制表符]万,但用户可能会直接输入340万。Hawk搜索是按照严格字符串匹配的,就会匹配不成功,因此输入短一些,如340
和 Chrome等浏览器得到的XPath不同
一方面,XPath的表示方法有很多种,这和正则类似。可能看起来不一样的XPath指代的都是同一个节点。 另一方面,Chrome会执行js代码,而js可能会改变网页的结构,因此XPath也就对应地发生变化了。这会通常会导致从Chrome拷贝出来的XPath在Hawk中不能使用。 Hawk未来不会考虑支持加入执行js代码的功能,因此,如果搜索XPath,还请以Hawk得到的结果为准。多搜多看,通常就能建立感觉。
1.6.手气不错的问题
很多人使用手气不错会失败。这是因为:
不是所有的网页都支持直接点击【手气不错】
手气不错需要特定的网页结构(列表),如果整个网页没有显著的列表节点,则搜索失败,此时就会提示 手气不错失败。
手气不错会自动规约父节点
使用手气不错后,嗅探器会找到列表节点的父节点,以及挂载在父节点上的多个子节点,从而形成一个树状结构:
- 父节点(/html/div[2]/div[3]/div[4])
- 子节点1(/a[1])
- 子节点2(/a[2]/@href)
- 其他省略 有时候,父节点的xpath是不稳定的,举个例子,北京上海的二手房页面,上海会在列表上面增加一个广告banner,从而真正的父节点就会发生变化。为了应对这种变化,通常的做法是手工修改【父节点XPath】,继续举例子,父节点的id为
house_list
,且在网页中全局唯一,你就可以使用另外一种父节点表示法//*[@id='house_list']
(写法可以参考其他XPath教程),而子节点表达式不变。 Hawk在【手气不错】得到【确定】后,会询问是否提取父节点XPath,此时Hawk会自动提取【父节点XPath】到属性对话框中,从而方便修改。
1.7.获得的页面与浏览器上不一样?
这非常常见,考虑到速度,Hawk不会动态执行js请求。而浏览器会大量执行js加载图片等,获得的源码可能有所不同,更不用说搜索得到的XPath了。但这样能获得百倍于浏览器的执行速度,因此这个缺点是值得的。
那如何抓取动态页面呢?对于这种情况,参考动态嗅探章节。
即使是同样的页面,用Hawk得到的XPATH与浏览器不一致,为什么呢?
一方面,XPath的表示方法有很多种,这和正则类似。可能看起来不一样的XPath指代的都是同一个节点。另一方面,Chrome会执行js代码,而js可能会改变网页的结构,因此XPath也就对应地发生变化了。这有可能会导致从Chrome拷贝出来的XPath在Hawk中不能使用。
Hawk未来不会考虑支持加入执行js代码的功能,因此,如果搜索XPath,还请以Hawk得到的结果为准。多搜多看,通常就能建立感觉。
1.8.一个网站要设置好多个页面,配置太繁琐!
可在系统状态视图
中,将网页采集器拖到下面的复制
图标上,即可复制多个采集器。这样可一定程度上简化操作。
当一组采集器需要同一组请求参数时,可设置共享源
自动同步,参考3.2采集器高级用法
的最后一节。
2.数据清洗
2.1.拖入从爬虫转换
后没有任何数据。
从爬虫转换
实际上搭建了采集器与数据清洗的桥梁,它要选择对应的网页采集器才行,
2.2.拖入从爬虫转换
后,数据有了,但之前的列消失了
参考 4.3转换器
中UDAF的特别说明
.
3.编译与运行问题
虽然在GitHub上是最新的代码,最新代码是可以成功编译的。但不能保证用户是否clone的是早期版本的代码,因此此处罗列可能的编译错误。
3.1.编译问题
-
从GitHub上拉回来的代码,默认启动路径是
Hawk.Core
,这导致编译成功,但运行时提示“无法直接启动带有类库输出类型的项目”: 将Hawk设置为解决方案的启动项目,参考这里:https://jingyan.baidu.com/article/4e5b3e1934c2fc91901e2426.html -
因为工程
Hawk.csproj
包含的两个图片文件不存在导致,在这些文件图标上点击右键,选择'排除出项目',即可正常编译。 -
找不到项目
System.Windows.???.WPFPropertyGrid.csproj
项目,有两种方法,一种是从作者的GitHub上clone对应的项目,并添加项目引用,另外一种做法是,删除项目引用,添加外部dll引用,所有的外部dll,都能在Include文件夹中找到。 -
大量的库找不到,几百个报错:
Hawk编译用了不少第三方类库,因此需要配置nuget,它是微软技术栈的pip,能自动安装所需的依赖,配置可参考这里:
https://docs.nuget.org/
3.2.启动后软件只有外边框,没有其他任何显示
老版本的Hawk(小于1.2)在Win7和Win8下的兼容性不佳,请升级最新版本的Hawk.
3.3.不小心关掉了某个侧边栏
Hawk采用了Visual Stuido风格的Dock系统,所有的布局都可以调节大小,设定位置,常见的错误是,不小心关闭了某个面板。如何恢复呢? 对于任务的窗口,双击任务应该就能恢复,如果是日志边栏,不好意思,恢复不了,重启软件吧。
4.宏观问题
和具体使用无关,主要涉及对一些吐槽的回答
4.1.为什么只支持Windows?
笔者曾是微软技术栈的粉丝,因此C#,WPF成了设计首选,如今虽然技术栈大大扩展,但用Js或其他语言重写成本太高,因此依然只提供Windows版本。 虽然笔者平时也只用MAC了...
4.2.为什么不提供更强的代理?
爬虫是一种灰色的应用,虽然作为Hawk的设计者,但我依然不得不这么说。
各大网站都在收集和整理数据上花费了大量的精力,因此抓取的数据应当仅仅作为科学研究使用。作者对Hawk的使用者的行为,不承担任何连带责任。
建议您理性使用爬虫,在不影响网站正常运营的情况下抓取数据。Hawk的好处是,较大地降低了爬虫的开发成本,能让普通用户也能使用。在这一理念下,我们仅仅提供最为实用的功能,而更多高级的功能则不会提供。比如代理切换和验证码识别。
在并行模式下,仅提供单机并行,而分布式并行也不会提供。尽管如此,我们还是会简单讨论如何验证码识别,代理和并行的问题。
代理实现并不复杂,在代码层面上只需要几行代码。但基于之前提过的原因,开源版本不提供代理的支持。
4.3.验证码识别?
验证码识别确实有难度,因为各大网站都不相同,简单的如普通四位数字验证码,难的如12306的变态验证码。因此提供通用的识别几乎是不可能的。
如果您愿意付费,并使用第三方的图形验证码服务,则可以将其配置为一个网页采集器,再调用之。
4.4.为什么只支持MongoDB和Sqlite?
Hawk在设计之初,就是以弱schema风格定义的。没有严格的列名和列属性。用C#这样的静态强类型语言编写Hawk,其实并不方便。但弱schema让Hawk变得更灵活更强大。
因此,Hawk虽然之前支持各种数据库连接器,而目前只支持MongoDB这样的文档型数据库。之所以不支持传统SQL,是因为获取的数据可能并不满足这些SQL数据库的约束:如列的顺序,列的字段类型,是否为空...很容易导致插入失败。使用Hawk的一般不是程序员,我不想给普通人挖这样的坑。
当然,从各类SQL数据库中读入数据也是可以的,但既然没有提供写入,我们也就索性不提供读入了。需要的话,你可以自己扩展其他数据库连接器。
不过,简单的才是最好的,以作者的经验,使用MongoDB这样的数据库来应对爬虫已经足够了:不需事先建表,高性能,低成本,低维护。我们也不可能一次性就把数据规约成你想要的形式,之后完全可以用其他工具和代码,再将MongoDB的数据导出来,写入到目标数据库。