最初学爬虫都是用requests库 + BeautifulSoup库的技术路线。对于一般的静态网页爬虫而言,这两个库完全足够应付。不过,写代码时比较麻烦的大概有两点:一是如果涉及到翻页,需要根据网址不断构造新的URL链接;二是如果不熟悉XPath或者CSS语法,要定位某个html标签还是挺费时间的。
如果要爬取的网页是动态的,也就是说我们实际需要的数据是异步加载的(嗯,其实我也不懂这是个啥,反正就是这些数据在通过requests.get请求返回的网页源代码里说找不到的。)面对动态网页,一般两种路径,一曰selenium模拟浏览器访问,一曰抓包。这几日刚学了selenium模拟,跑个代码试试。
这次要爬取的是证监会关于IPO企业预披露的网站
这么规整的数据,直接ctrl+c加ctrl+v就行了呀,还写什么爬虫。但作为一个爬虫小白,本着不放过任何一个锻(zi)炼(nue)的机会的气质,一定要写出来,哪怕再烂。
网页的地址是这样的:http://ipo.csrc.gov.cn/checkClick.action?choice=info#,一共需要爬67页。而且,每一页的网址都是一样的,不管你怎么戳鼠标,它就在那里,依然如故。
这样的网址设计对requests很不友好(其实是对爬虫小白很不友好)。另外,源代码也毫无意外的没有我所需要的公司信息。数据藏在哪里了?
查找数据,知道switch frame
打开控制台,查找表格里的任意一个元素。很幸运,还是能找到的。比如:
分析页面元素,发现数据表格实际上是一个单独完整的html文本,内嵌在原来的外层网页中,而在源代码网页文件中,这个内嵌的html文本是看不见的。
这种情况下,就充分体现出selenium的强大了。利用driver.switch_to.frame('myframe)直接定位该内嵌网页,然后就可以轻松获得html文件了,即html=driver.page_source。后面提取网页数据就基本上是beautifulsoup的事情了。
click()方法翻页
在面对静态网页时,网址中会出现跟页数有关的信息。比如,豆瓣评论的网址“https://movie.douban.com/subject/25837262/comments?start=20&limit=20&sort=new_score&status=P&percent_type=”,通过其中的start和limit参数就能确定页码。
如果是用selenium模拟浏览器访问页面,就不需要再分析网址信息,而是可以直接用find_element_by_class_name等函数定位到页面上的“下一页”按钮,然后利用click()方法,就像是用鼠标点击了一样,页面就自动跳转到下一页了。
运行的时候,我们就可以静静的看着网页在自己的电脑屏幕上飞了,感觉自己会了魔法哈哈哈哈!
控制好driver
当运行了clikc()方法导致翻页之后,driver对象本身就会自动发生变化,那些与driver对象有关的变量也发生了变化,全部需要重新赋值,否则程序会报错。
习惯用类写代码
用代码完成一件任务,其实就是将任务拆分到不同的功能模块。模块最小的单位就是一个个的函数。以前写代码,直接写各个函数就好了。接触到scrapy框架等工程思维之后,发现更多的人都是把函数封装在类当中。通过类,可以更方便函数以及模块之间的调用。对于工程量稍大一些的项目,采用类的方式也能直观。
爬这个网站最主要的目的
如果只是要得到像网站那样的表格数据,直接复制粘贴确实更省时间,毕竟也就不到100页的数据。但是,如果要把每家公司的预披露文件下载并按公司重命名呢?
我爬网站最主要的目的就是获取每份预披露文件的超链接地址。有了地址,就可以用urllib.request.urlretrieve方便的下载文档了。尽管目前来讲,这些文档没什么用了。不过,也算是达到练手的目的了。
(还是没有插图,作者太懒了)