php网页抓取乱码(一下爬虫乱码的解决方法有哪些?时出现了问题)
优采云 发布时间: 2022-01-29 11:14php网页抓取乱码(一下爬虫乱码的解决方法有哪些?时出现了问题)
现在越来越多的人在学习爬虫程序,难免会在学习中遇到问题,比如爬取时出现乱码等。跟大家分享一下爬虫乱码的解决方法。
网络爬虫有两种选择,一种是nutch、hetriex,一种是自编译爬虫。处理乱码的时候,原理是一样的,但是处理乱码的时候,前者只能在理解后修改源代码,所以要浪费一些精力;后者更加自由方便,可以在编码过程中处理。这也是很多人在用框架写爬虫的时候没有开始的原因。比如比较成熟的nutch在处理乱码方面比较简单,所以还是会出现乱码,所以需要二次开发才能真正解决乱码问题。
1、网络爬虫出现乱码的原因
源页面的编码与爬取后的编码转换不一致。如果源网页是gbk编码的字节流,程序爬取后直接用utf-8编码输出到存储文件,难免会造成乱码,即源网页编码时程序爬取编码一致时不会出现乱码,统一字符编码后不会出现乱码。注意区分源网络代码A、程序直接使用的代码B、统一转换字符的代码c。
A. 是网页的服务端编码
B. 抓取的数据最初是一个字节数组,由A编码。只有B=A时才能没有乱码,否则在字符集不兼容的情况下总会出现乱码。此步骤通常用于测试。
C、统一转码是指得到网页的原码A后进行统一编码,主要是将各个网页的数据统一为一种编码,通常选择字符集较大的utf-8比较合适。
每个网页都有自己的编码,比如gbk、utf-8、iso8859-1,还有日系jp系统编码,西欧、俄文等编码都不一样,爬的时候总会展开出各种编码,有的爬虫对网页进行简单的编码识别,然后进行统一编码,有的不判断源页面,直接按照utf-8处理,显然会造成乱码。
2、乱码的解决方法
(1)程序通过编码B恢复源网页数据
很明显,这里的B等于A。在java中,如果得到的源网页的字节数组是source_byte_array,那么就转换为String str=new String(source_byte_array, B); 也就是内存中的这些字节数组对应的字符被正确编码并可以显示,此时的打印输出是正常的。这一步通常用于调试或控制台输出进行测试。
(2)确定源网页的编码A
代码A通常位于网页中的三个位置,http头的内容,网页的元字符集,以及网页头中的Document定义。在获取源网页的代码时,依次判断这三部分数据就足够了,而且从前到后优先级也是一样的。
这个理论上是对的,但是国内有的网站确实是很不合规的,比如gbk,其实是utf-8,有的是utf-8,其实是gbk,当然这个很A小批量 网站,但它确实存在。因此,在确定网页代码时,应针对特殊情况进行特殊处理,如中文校验、默认代码等策略。
还有一种情况是以上三种都没有编码信息,一般使用第三方网页编码智能识别工具如cpdetector来做。准确率,但我实际上发现准确率仍然非常有限。
不过结合以上三种编码确认方式后,中文乱码问题几乎可以完全解决。在我基于nutch1.6二次开发的网络爬虫系统中,据统计正确编码可以达到99.的99%,这也证明了上述方法策略的可行性。
(3) 统一转码
网络爬虫系统的数据来源很多,当无法使用数据时,就会将其转换成它的原创数据,即使这样做是非常没用的。所以一般的爬虫系统应该对抓取到的结果进行统一编码,这样就可以统一对外使用,方便使用。这时候在(2)的基础上,可以做一个统一的编码转换。java中的实现如下
源网页的字节数组是source_byte_array
转换成普通字符串:String normal_source_str=new String(source_byte_array, C),可以直接用java api存储,但很多时候不直接写字符串,因为一般爬虫存储是存储多源web pages 合并到一个文件中,所以需要记录字节偏移量,所以下一步。
然后将得到的str转换成统一编码C格式的字节数组,然后byte[] new_byte_array=normal_source_str.getBytes©,然后可以使用java io api将数组写入文件并记录对应的字节数组Offset等。实际使用时,可以直接通过io读取。
以上方案可以解决爬取时出现乱码的问题。爬取信息不仅会出现乱码,还有网站爬取涉及法律、IP封禁、IP限制等,如何避免IP封杀?为了防止ip被屏蔽,我们需要使用代理ip软件。一直在用**可变ip**,全国城市ip,自动去重,百万优质动态ip每天可使用,支持http/https/socks5三大协议!