最近使用node.js写了一个爬知乎的爬虫,用来爬取用户的个人信息,主要是个人主页的内容,这里主要介绍一下在这个过程中遇到的问题和整个项目的结构。
遇到的问题
1.由于知乎打开之后,显示的数据量是有限的,只有在右侧滚动条滚动到底部的时候,才会显示下一页的信息,是异步获取数据的,所以不能通过解析html获得,需要观察后台发送的异步请求来找到获取数据的来源。
如何知道前前端是通过哪个url获取数据的呢?
在你打开知乎的个人主页之后,按F12,打开浏览器的调试界面(我使用的是chrome),点击最上面一栏的network, 然后点击右下的response,点击左侧的一个个url,当Response下显示的是一个json数据的时候,这就很有可能是一个异步的前段请求。你需要通过你的爬虫调用这个url来获取异步加载的数据,直接解析返回的json格式的数据就可以了。
2.在for循环里使用异步操作。由于使用异步操作可以极大加大数据的吞吐量,所以在程序的各个地方使用异步。如果在for循环中使用异步,就会导致很严重的问题,由于for循环结束地比异步早,所以就会导致异步操作中所有使用到i(for循环里的参数)的地方,都是for循环执行完最后一次的值,所以最后使用async在for循环中使用同步操作。
项目的整体结构
项目主要由三个部分组成
(1)数据库交互模块,主要用于与数据库进行交互,使用了mongoose
(2)用户信息获取模块,主要用于访问特定的url获取某个用户的数据,然后进行处理后,存储进数据库,是项目的最主要部分
(3)线程控制模块,会根据cpu的数量,开启多个线程,进行用户数据的获取,多线程可以提高数据的吞吐量。
项目中数据的大体流程如下:在数据库中读取某个用户token -->> 拼装url来获取这个用户的详细信息,并存入数据库 -->> 将用户所关注的人的token存入数据库中,作为下一个需要爬取的用户 -->> 在数据库中随机读取一个没有被爬取过的用户爬取他的详细信息-----循环不止。
最后附上项目的github(https://github.com/majinliang123/zhihu-crawler)地址,欢迎各位的star和pull request。