手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 免费部署 N8N 的 Zeabur 注册 | 登陆
浏览模式: 标准 | 列表全部文章

hongyin163:网页信息抓取实现

突然怀念起几年前,walkerlee、hihiyou、我还在为了NC进行打拼,也曾为了某个正则几乎通宵不睡在测试。其实在NC前已经有过多款的采集软件,但其实都是属于功能单一情况,如:开花石头的逆向小偷等。NC只是一款整合了一起功能的采集软件,也算是开创了先河吧?反正自那以后,采集程序越来越多,先是剑枫,然后是小蜜蜂,再后来是火车头,采集软件越来越多之后,随之而来的就是性能问题,采用WEB方式的采集,不可避免的就是性能。你没有办法控制一个WEB页面不会超时,而且PHP由于自身的执行方式,也就不可能是多线程执行,后来大多数人,采用了iframe的方式,让一个页面打开十个左右的iframe然后根据执程的ID来进行判断。

过去的事情,总是让人怀念,在看到这个作者写类似的采集时,感慨的同时,留一份备份,以作纪念

原文:http://www.cnblogs.com/hongyin163/archive/2009/02/11/1388615.html
内容:

最近公司需要开发一个简历导入功能,类似博客搬家或者邮箱搬家,之前抓取信息是利用火车采集器,但是简历导入功能需要用户登陆以后才能获取简历数据,无奈只好自己开发了。

首先是遇到的问题是:如何实现模拟登陆?

我们知道一般的网站都是通过Cookies来维护状态的,我抓的网站也是支持利用Cookies来验证用户的,构造一个post数据包,向服务器提 交数据,在配置火车采集器的时候,也是要先利用WSockExpert.exe工具获得Post数据包,之后修改用户名和密码,向服务器提交的。

提交了登陆数据后还没完成登陆,虽然服务器会返回登陆后的页面数据,但是如果在进入其他的链接页面,还是不允许的,因为服务器每次都需要通过你提交 过去Cookies来验证你是否登陆,在asp.net里,利用Cookies存储身份验证票证,每次都需要向服务器提交的,初学asp.net总是弄不 明它的form验证机制,它封装了太多信息,虽然用几行代码就能实现验证,后来看了些web开发基础知识才弄明白,在这个你需要保存上次登陆后返回的 Cookies,在下次有其他请求时带上这个Cookies就可以了,怎么带上呢?下面是我在.net里的实现,很简单!

利用HttpWebRequest类的CookieContainer来保存,这个CookieContainer会保存服务器回传的 Cookies,但是前提是你在初始化HttpWebRequest的时候,记得实例化这个CookieContainer,一般的请求不需要实例它的, 简单的代码如下:

 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(URL);            
  httpWebRequest.CookieContainer = new CookieContainer();
  httpWebRequest.ContentType = "application/x-www-form-urlencoded";
 httpWebRequest.Method = "POST"

 为了能全局使用这个CookieContainer ,你可以把它作为全局变量,这样在下次request的时候将其赋给CookieContainer 属性就行了。

详细了解CookieContainer 见:http://msdn.microsoft.com/zh-cn/vstudio/system.net.cookiecontainer(VS.80).aspx

维护了这个CookieContainer 后,我们就可以访问登陆后的页面了,模拟登陆问题解决。

其次遇到的问题自然是:如果从网页上获得想要的信息?

 要在网页抓取信息,实现起来最简单,同时也是最繁琐的方法,那就是模板方法获取了,从火车采集器的配置过程看出来,它也就是用这种方法而已,不过 人家能把抓取器做成成熟的产品,并且热卖,这个比不了,所以成功与否不完全取决于技术,火车采集器虽然配置起来挺繁琐,但是用起来还不错。

用这种方式你需要做个一个模板,你需要知道目标网页的结构,知道要找的信息在什么地方,之后记录在它的前面和后面的字符串,你可以利用截取字符串的 方式获得目标信息,也可以利用正则标式获得,要保证前面和后面的字符串是唯一的,很简单,计算一下,或者匹配一下就可以获得目标信息,但是实际做起来还是 会遇到一些问题:

下面是我遇到问题;

1.首先我是想利用正则表达式匹配,但是模块里设置的前缀和后缀里有回车换行\r\n,结果总是匹配不成功,我正则的功底很差,最后知道怎么回事了,把\r\n替换成(\s*),问题解决,您可以想出为什么了吧?

2.利用字符串截取方式获取,在正则还不是很精通,用这种方式最保险了,但是在截取字符串前记得调整下目标页代码,从xml配置文件里读取的前缀和 后缀中可能有回车和换行,但是回车换行在不同系统里字符表现是不一样的,Windows里是\r\n,Linux里是\n,所以要记得统一。

3.前后缀不唯一,有时在页面里有两个不同的目标信息,但却有相同的前缀,比如:

<td width="25%" class="ResTbLfPd">数据库</td>
<td width="25%" class="ResTbLfPd">软件工程师</td>

如果用相同的前缀就比较难截到想要的信息了,我想了个办法,当然方法可能比较笨,但是问题解决了,也是火车给我的启示,利用多个字符串定位目标信息,比如我想抓去 软件工程师 ,前缀就是:

<td width="25%" class="ResTbLfPd">*</td>
<td width="25%" class="ResTbLfPd">

在信息可能不同的地方用*代替,类似通配符,这样利用*将一个字符串切割为两个,先找到第一个,之后以这个索引位置为起点,再找第二个字符串,这样就可以定位到最终的信息了,同样可以用多个字符串三个或更多,这样实现是解决了问题,希望有更好的方式,希望以后会改进。

4.在抓取信息的时候还可以利用MITHtmlPparser,这是一个开源的类库,在codeproject找搜到的,将网页内的所以标签都分析出来,如果获取信息不是很多、很碎的话,用这个也比较好用,只需知道那个最终要得到信息在那个标签里,然后直接取出就行了。

好了,希望在新的一年里能学到更多,能经得住考验!

Tags: 采集

ZendStudio.Net:某网站AJAX的加密压缩传输算法的一点研究

题前话:
其实以前也看到过类似的东西,但是我没有想到进用gzip之类的加密,看来,即使是见过的东西,也有不熟悉的。看到作者这样仔细的分析相类似的资料,当然要备份一点。
原文:http://www.zendstudio.net/js-zip-inflate/
AJAX还是比较强大的!(显然,这是一句废话),最近在研究一个网站的AJAX应用中发现其中的“拓展视野”部分频频被挖掘出来(也由此可见,平时本人 的视野有多么的狭窄了),首先是全站的JS全部使用packed进行了压缩,呃!也不知道这种称法是否正确,就是用 eval(function(p,a,c,k,e,d){})的那种世界各地都很流行的压缩方法吧,在实际的观察中,一个压缩后仅为6K,在我将其转化为 “肉眼能看清楚的代码”之后,足足有20K,可见其效果还是相当明显的;此外,用HttpWatch弄到了传输数据后,居然是加密的。。。形如下面这段:

XML/HTML代码
  1. q1YqT81MzyhRsqpWys3MU7Iy0FHKTaxQsjLWUUrLL8pNBMooqeoZpSnV6igVFGUmp2KoVDIzMrIwNdAzMFBC1pOiVFsLAA==  

任何一个有些许密码学经验的同志都容易很看出来,这是base64编码(我实在不喜欢称这个为“加密”),没错,和各位看官一样,我很快就用php自带的base64_decode函数对其进行了解密,如果您觉得问题到此为止,那就错了!这时我才稍稍感到了有些震撼,解密出来的数据:
大小: 6.92 K
尺寸: 500 x 50
浏览: 1724 次
点击打开新窗口浏览全图
呃!一堆乱码,其实应该是二进制数据,加密了(后来知道是压缩了),可是用户是看不懂这些的,客户端是肯定要进行解密的!用什么?AJAX的当然用JS解密了,挖解密函数啊,挖解密函数,看到了如下的精彩代码:

JavaScript代码
  1. var filterList=eval('('+utf8to16(zip_depress(base64decode(g_pgFilterList)))+')');  

utf8to16()和base64decode()都好理解,也再一次证明加密的最后是用base64编码输出的,关键就是这个zip_depress(),zip解压?
是的,千真万确,用JS实现了zip的解压算法!!!到这里我深深的感到了震撼,原来,我知道的真的太少了啊!虽然之前知晓有md5.js,知道JS在运算方面是没有问题的。不会是这家伙自己写的压缩算法吧?经过搜索,我找到了这个算法(Zip inflate)的原版,原来该网站的制作人员修改了函数名,难怪我直接google不到呢?

什么是inflate算法?—
  1. inflate是GZip, PNG等广泛使用的解压算法,linux也使用inflate对内核进行解压.inflate的解压算法使用的第3种快速解压法的一个子集,它不考虑 LONG_CODE,同时把SAME_LENGTH合并到MEDIUM_CODE。而对于规则的SAME_LENGTH编码,比如length和 distance编码,inflate则使用额外的base和extra表示。这是因为在构造一般的查找表时,虽然对于SAME_LENGTH前缀可以不构造副表,但我们需要另外一个表格来保存符号的顺序,而这个表格的空间可能更大。但对于length和distance编码,他们的顺序是递增的,所以无需额外的表格来保存符号的顺序。  
  2.   
  3. inflate使用root表示上述的b,查找表的数据结构为code.主表和副同时保存在inflate_state结构中的大数组codes[ENOUGH]中.表的构造函数位于inftrees.c文件的inflate_table中.  
令人感到欣喜若狂的是,PHP竟然已经提供的现成函数来解压和压缩inflate,它们是gzinflate()gzdeflate(),哈哈哈!我不禁仰天狂笑的一番,用gzinflate()成功的将上文数据解密,内容是这样的:

JavaScript代码
  1. {"weight":{"min":0,"max":3,"format":"%.2f"},"price":{"min":0,"max":"622850.00","format":"%d"}}  

标准的JSON数据啦,不错!这就为以后的AJAX的传输上多了一个选择,虽然还不确定这种方法能否节省流量(因为base64算法会将原始数据“稍稍” 增大),但客户端有了解压算法,服务端的php压缩函数又是现成的,大不了在base64这个环节上大概需要改进下,我想对于大流量的数据应该还是有确切 效果的。嗯,我很满意。
————————
看完以上的内容,嗯,我也很满意,呵呵

备忘:学习回忆未来上的一些技术

给自己提醒, 回忆未来张宴的网站上有一些例子不错,正好自己又装了虚拟机,看来是应该根据这些资料好好的学习一下了。这样也可以让自己更加熟悉linux下面的操作。

再次提醒自己
呵呵。不能忘了

Tags: 备忘, 回忆未来, 技术

[笔记]在ubuntu下安装amp服务

目前我还是利用系统自带的apt来进行安装的,所以相对还是比较简单的:
apt-get install apache2.2-common apache2 php5-mysql  mysql-server-5.0 mysql-client mysql-common
就可以直接安装了。安装过程中会有提示你设置MYSQL的密码,主要是指ROOT的。

如果是用新立得安装那就更简单了,只要根据你需要的模块进行安装就行了。(以前我都是这样搞的,但是这次是用的SERVER,没法直接用新立得)

顺便说一下,网易的源速度真的不错。
感谢网易在开源方面的贡献。谢谢

使用默认的apt-getp安装的时候,它的配置在/etc/apache2/apache2.conf里,而不是大家所熟知的httpd.conf,而virtualhost的配置是在/etc/apach2/site-enabled/目录里,里面有一个默认的000-default文件,这就是默认的webroot的配置,我们可以很清楚的看到,webroot被定义在/var/www目录下面

由于是使用 apt 进行的安装,所以对于PHP等的扩展,也必须使用 apt才行,否则你会感觉到很迷惘。

Tags: ubuntu, lamp

[笔记]Ubuntu下修改网卡和DNS

纯粹是记录吧。在使用 UBUNTU 的时候,如果是ubuntu desktop,那配置起来是相当简单的,就象windows那样配置就行了,但如果是ubuntu server,怎么配置呢?当然是用ifconfig了。
很简单的命令:
ifconfig eth0 192.168.1.2 broadcast 192.168.1.1 netmask 255.255.255.0

  1. eth0是代表第一块网卡,因此,如果你不确认的时候,必须要使用ifconfig查看一下有几块网卡,想配置的是不是eth0
  2. 192.168.1.2是想要配置的IP
  3. broadcast 192.168.1.1 代表了网关
  4. netmask 就是子网掩码了

这样配置完还是不能上网的,因为还没有配置DNS,然后 vi /etc/resolv.conf ,在文件里加入:nameserver 202.96.209.133 ,当然这是上海地区所使用的DNS,有常见的几条,统统加进来就行了。

最后在命令行下执行:/etc/init.d/networking start,对刚才的配置进行重新启动,激活一下网卡配置。
OK,就可以上网了。。

后来我又看了点资料,发现网上还是有详解的:

http://blog.ixpub.net/html/54/12634654-245464.html
  1. ifconfig 是一个用来查看、配置、启用或禁用网络接口的工具,这个工具极为常用的。可以用这个工具来临时性的配置网卡的IP地址、掩码、广播地址、网关等。也可以把它写入一个文件中(比如/etc/rc.d/rc.local),这样系统引导后,会读取这个文件,为网卡设置IP地址  
  2. 1 ifconfig 查看网络接口状态;  
  3.   
  4. ifconfig 如果不接任何参数,就会输出当前网络接口的情况;  
  5.   
  6. [root@localhost ~]# ifconfig  
  7. eth0      Link encap:Ethernet  HWaddr 00:C0:9F:94:78:0E  
  8.           inet addr:192.168.1.88  Bcast:192.168.1.255  Mask:255.255.255.0  
  9.           inet6 addr: fe80::2c0:9fff:fe94:780e/64 Scope:Link  
  10.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
  11.           RX packets:850 errors:0 dropped:0 overruns:0 frame:0  
  12.           TX packets:628 errors:0 dropped:0 overruns:0 carrier:0  
  13.           collisions:0 txqueuelen:1000  
  14.           RX bytes:369135 (360.4 KiB)  TX bytes:75945 (74.1 KiB)  
  15.           Interrupt:10 Base address:0x3000  
  16.   
  17. lo        Link encap:Local Loopback  
  18.           inet addr:127.0.0.1  Mask:255.0.0.0  
  19.           inet6 addr: ::1/128 Scope:Host  
  20.           UP LOOPBACK RUNNING  MTU:16436  Metric:1  
  21.           RX packets:57 errors:0 dropped:0 overruns:0 frame:0  
  22.           TX packets:57 errors:0 dropped:0 overruns:0 carrier:0  
  23.           collisions:0 txqueuelen:0  
  24.           RX bytes:8121 (7.9 KiB)  TX bytes:8121 (7.9 KiB)  
  25.   
  26. 解说:  
  27. eth0 表示第一块网卡, 其中 HWaddr 表示网卡的物理地址,可以看到目前这个网卡的物理地址(MAC地址)是 00:C0:9F:94:78:0E ; inet addr 用来表示网卡的IP地址,此网卡的 IP地址是 192.168.1.88,广播地址, Bcast:192.168.1.255,掩码地址Mask:255.255.255.0  
  28.   
  29. lo 是表示主机的回坏地址,这个一般是用来测试一个网络程序,但又不想让局域网或外网的用户能够查看,只能在此台主机上运行和查看所用的网络接口。比如把 HTTPD服务器的指定到回坏地址,在浏览器输入 127.0.0.1 就能看到你所架WEB网站了。但只是您能看得到,局域网的其它主机或用户无从知道;  
  30.   
  31. 如果想知道主机所有网络接口的情况,请用下面的命令;  
  32. [root@localhost ~]# ifconfig -a  
  33.   
  34. 如果想查看某个端口,比如查看eth0 的状态,就可以用下面的方法;  
  35. [root@localhost ~]# ifconfig eth0  
  36.   
  37.   
  38. 2 ifconfig 配置网络接口;  
  39.   
  40. ifconfig 可以用来配置网络接口的IP地址、掩码、网关、物理地址等;值得一说的是用ifconfig 为网卡指定IP地址,这只是用来调试网络用的,并不会更改系统关于网卡的配置文件。如果您想把网络接口的IP地址固定下来,目前有三个方法:一是通过各个发行和版本专用的工具来修改IP地址;二是直接修改网络接口的配置文件;三是修改特定的文件,加入ifconfig 指令来指定网卡的IP地址,比如在redhat或Fedora中,把ifconfig 的语名写入/etc/rc.d/rc.local文件中;  
  41.   
  42. ifconfig 配置网络端口的方法:  
  43.   
  44. ifconfig 工具配置网络接口的方法是通过指令的参数来达到目的的,我们只说最常用的参数;  
  45. ifconfig 网络端口 IP地址 hw <HW> MAC地址 netmask 掩码地址 broadcast 广播地址 [up/down]  
  46.   
  47. * 实例一:  
  48. 比如我们用ifconfig 来调试 eth0网卡的地址  
  49. [root@localhost ~]# ifconfig eth0 down  
  50. [root@localhost ~]# ifconfig eth0 192.168.1.99 broadcast 192.168.1.255 netmask 255.255.255.0  
  51. [root@localhost ~]# ifconfig eth0 up  
  52. [root@localhost ~]# ifconfig eth0  
  53. eth0 Link encap:Ethernet HWaddr 00:11:00:00:11:11  
  54.           inet addr:192.168.1.99 Bcast:192.168.1.255 Mask:255.255.255.0  
  55.           UP BROADCAST MULTICAST MTU:1500 Metric:1  
  56.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0  
  57.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0  
  58.           collisions:0 txqueuelen:1000  
  59.           RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)  
  60.           Interrupt:11 Base address:0x3400  
  61.   
  62. 注解: 上面的例子我们解说一下;  
  63.   
  64. 第一行:ifconfig eth0 down 表示如果eth0是激活的,就把它DOWN掉。此命令等同于 ifdown eth0;  
  65. 第二行:用ifconfig 来配置 eth0的IP地址、广播地址和网络掩码;  
  66. 第三行:用ifconfig eth0 up 来激活eth0 ; 此命令等同于 ifup eth0  
  67. 第四行:用 ifconfig eth0 来查看 eth0的状态;  
  68.   
  69. 当然您也可以用直接在指令IP地址、网络掩码、广播地址的同时,激活网卡;要加up参数;比如下面的例子;  
  70. [root@localhost ~]# ifconfig eth0 192.168.1.99 broadcast 192.168.1.255 netmask 255.255.255.0 up  
  71.   
  72. * 实例二:在这个例子中,我们要学会设置网络IP地址的同时,学会设置网卡的物理地址(MAC地址);  
  73.   
  74. 比如我们设置网卡eth1的IP地址、网络掩码、广播地址,物理地址并且激活它;  
  75. [root@localhost ~]# ifconfig eth1 192.168.1.252 hw ether 00:11:00:00:11:11 netmask 255.255.255.0 broadcast 192.168.1.255 up  
  76. 或  
  77. [root@localhost ~]# ifconfig eth1 hw ether 00:11:00:00:11:22  
  78. [root@localhost ~]# ifconfig eth1 192.168.1.252 netmask 255.255.255.0 broadcast 192.168.1.255 up  
  79.   
  80. 其中 hw 后面所接的是网络接口类型, ether表示乙太网, 同时也支持 ax25 、ARCnet、netrom等,详情请查看 man ifconfig ;  
  81.   
  82.   
  83. 3.3 如何用ifconfig 来配置虚拟网络接口;  
  84.   
  85. 有时我们为了满足不同的需要还需要配置虚拟网络接口,比如我们用不同的IP地址来架运行多个HTTPD服务器,就要用到虚拟地址;这样就省却了同一个IP地址,如果开设两个的HTTPD服务器时,要指定端口号。  
  86.   
  87. 虚拟网络接口指的是为一个网络接口指定多个IP地址,虚拟接口是这样的 eth0:0 、 eth0:1、eth0:2 ... .. eth1N。当然您为eth1 指定多个IP地址,也就是 eth1:0、eth1:1、eth1:2 ... ...以此类推;  
  88.   
  89. 其实用ifconfig 为一个网卡配置多个IP地址,就用前面我们所说的ifconfig的用法,这个比较简单;看下面的例子;  
  90. [root@localhost ~]# ifconfig eth1:0 192.168.1.251 hw ether 00:11:00:00:11:33 netmask 255.255.255.0 broadcast 192.168.1.255 up  
  91. 或  
  92. [root@localhost ~]# ifconfig eth1 hw ether 00:11:00:00:11:33  
  93. [root@localhost ~]# ifconfig eth1 192.168.1.251 netmask 255.255.255.0 broadcast 192.168.1.255 up  
  94.   
  95. 注意:指定时,要为每个虚拟网卡指定不同的物理地址;  
  96.   
  97. 在 Redhat/Fedora 或与Redhat/Fedora类似的系统,您可以把配置网络IP地址、广播地址、掩码地址、物理地址以及激活网络接口同时放在一个句子中,写入/etc/rc.d/rc.local中。比如下面的例子;  
  98. ifconfig eth1:0 192.168.1.250 hw ether 00:11:00:00:11:44 netmask 255.255.255.0 broadcast 192.168.1.255 up  
  99. ifconfig eth1:1 192.168.1.249 hw ether 00:11:00:00:11:55 netmask 255.255.255.0 broadcast 192.168.1.255 up  
  100.   
  101. 解说:上面是为eth1的网络接口,设置了两个虚拟接口;每个接口都有自己的物理地址、IP地址... ...  
  102.   
  103.   
  104. 3.4 如何用ifconfig 来激活和终止网络接口的连接;  
  105.   
  106. 激活和终止网络接口的用 ifconfig 命令,后面接网络接口,然后加上 down或up参数,就可以禁止或激活相应的网络接口了。当然也可以用专用工具ifup和ifdown 工具;  
  107. [root@localhost ~]# ifconfig eth0 down  
  108. [root@localhost ~]# ifconfig eth0 up  
  109. [root@localhost ~]# ifup eth0  
  110. [root@localhost ~]# ifdown eth0  
  111.   
  112. 对于激活其它类型的网络接口也是如此,比如 ppp0,wlan0等;不过只是对指定IP的网卡有效。  
  113.   
  114.   
  115. 注意:对DHCP自动分配的IP,还得由各个发行版自带的网络工具来激活;当然得安装dhcp客户端;这个您我们应该明白;  
  116.   
  117. 比如Redhat/Fedora  
  118. [root@localhost ~]# /etc/init.d/network start  
  119.   
  120. Slackware 发行版;  
  121. [root@localhost ~]# /etc/rc.d/rc.inet1  

Tags: ubuntu, ifconfig, resolv