使用selenium等待网页加载完成,lxml解析网页,利用urllib爬取图片

来源:互联网 发布:淘宝店怎么管理 编辑:程序博客网 时间:2024/06/02 03:16

本来想爬六维空间(http://bt.neu6.edu.cn/)的搞笑图片来着。。。不知道为啥这两天上不去了。。。

于是就拿品知人大试一下python的这两个库。

用到的lxml函数可以参考:http://lxml.de/api/lxml.html.HtmlElement-class.html

主要的思路就是利用urllib获取网址内容,利用lxml解析特定规则的url。


要爬取的网页起始地址是:http://bt.ruc6.edu.cn/b/forum-36-1.html


一般写一个有递归逻辑的程序时,我喜欢先从最小的可以完成的单位写起。

那么,第一步,先点开一页,找一个图片的url,试一下能不能爬下来。

正好看到有一个我校『大白』的帖子(http://bt.ruc6.edu.cn/b/thread-222560-1-1.html)。ps:大白是学校里的一只流浪猫,据学校的流浪动物之家发的消息看,大白应该是3月初左右被中关村的一位漂亮的 IT MM 收养了。

第一张大白图片地址:http://bt.ruc6.edu.cn/b/data/attachment/forum/201604/14/215736wyrrrip32633fiaf.jpg

代码:

def get_page_string(url): # 因为获取网页字符串比较常用,所以就单独写成一个函数。    return urllib.urlopen(url).read()def save_img(url):    file_name = url.split('/')[-1] # 直接用网页上的图片名作为保存到本地的图片名    if os.path.exists('pic/' + file_name):        pass    else:        with open('pic/' + file_name, 'w') as of:            of.write(get_page_string(url))

(为了简单方便起见,很多异常处理的代码都没有加,也不需要反爬虫。。。)大白照片见文章末尾。


第二步,找到这一页的想要爬取图片的url。

首先看一下,这几幅图片的xml路径

//*[@id="aimg_270475"]//*[@id="aimg_270474"]//*[@id="aimg_270473"]。。。
看起来挺有规律的样子。不过,因为不知道其它的网页中的图片的id是怎么个样子,直接用id来爬并不好。

观察一下,发现这一页的所有图片都在标签是『td』中,而且其class属性是『t_f』。随便打开一个其它的网页也是这样的。那就暂时用这个线索来查找图片。

def iter_img(url):    try:        print get_page_string(url)        doc = lxml.html.document_fromstring(get_page_string(url)) # 从网页的字符串中得到一个基本的HtmlElment,用于调用lxml提供的函数。        element_class = doc.find_class('t_f')[0]# 这个返回的是一个数组,为了方便,只留第一个就行了。        imgs = element_class.findall('.//img') # 找到这个路径下面所有的,标签是img的元素。        for img in imgs:            print img.attrib['src'] # 打印出属性为『src』的内容    except:        pass # 有时候请求不到就算了。。

试了一下,竟然没有返回结果。是网页保存到本地,再通过JS动态加载内容的吗?

那只好用selenium里面的WebDriverWait函数,等网页加载好了再解析喽。。

对于mac和linux的操作系统,要有一个Chromedriver。 在 http://download.csdn.net/detail/hooo/7819273 上下载。然后放到 /usr/local/bin/ 下。并将其权限改成可执行。

selenium里面的一些函数与lxml细节上有些出入,但整体思想并没有什么变化。用的时候,到它官网上找一下函数说明即可。

def iter_img_page(pageURL):    driver = Chrome() # 调用浏览器    driver.get(pageURL)    WebDriverWait(driver, 100).until(lambda x: x.find_element_by_xpath('.//ignore_js_op'))    imgs = driver.find_elements_by_xpath('.//ignore_js_op/img') # 找到相应的标签。    for img in imgs:        img_url = img.get_attribute('src')# 打印出属性为『src』的内容        print img_url        save_img(img_url)



个人感觉,因为现在的框架实在是太多,一个人没必要也没那么多的时间去学。只要用的时候知道哪里去找就行了。

这次测试的完整代码如下:

#!/usr/bin/python# -*- coding:utf-8 -*-# Author: lizhenyang_2008@163.com# This python program is used to draw pictures from bt.ruc6.edu.cnimport lxml.html # 用于解析htmlimport osfrom selenium.webdriver import Chromefrom selenium.webdriver.support.ui import WebDriverWaitimport urllib # 用于抓取网页内容rootURL = 'http://bt.ruc6.edu.cn/b/forum-36-1.html'dabaiURL = 'http://bt.ruc6.edu.cn/b/data/attachment/forum/201604/14/215736wyrrrip32633fiaf.jpg'dabaiPageURL = 'http://bt.ruc6.edu.cn/b/thread-222560-1-1.html'def get_page_string(url): # 因为获取网页字符串比较常用,所以就单独写成一个函数。    return urllib.urlopen(url).read()def save_img(url):    file_name = url.split('/')[-1] # 直接用网页上的图片名作为保存到本地的图片名    if os.path.exists('pic/' + file_name): # 把图片放到本目录的'pic'文件夹下        pass # 要是文件存在就不处理了。    else:        print 'saving', url        with open('pic/' + file_name, 'w') as of:            of.write(get_page_string(url))def iter_img(url): # 因为网页内容不是一次返回到客户端,所以这个函数就没用到。    try:        print get_page_string(url)        doc = lxml.html.document_fromstring(get_page_string(url)) # 从网页的字符串中得到一个基本的HtmlElment,用于调用lxml提供的函数。        element_class = doc.find_class('t_f')[0]# 这个返回的是一个数组,为了方便,只留第一个就行了。        imgs = element_class.findall('.//img') # 找到这个路径下面所有的,标签是img的元素。        for img in imgs:            print img.attrib['src'] # 打印出属性为『src』的内容    except:        pass # 有时候请求不到就算了。。def iter_img_page(pageURL):    driver = Chrome() # 调用浏览器    driver.get(pageURL)    WebDriverWait(driver, 100).until(lambda x: x.find_element_by_xpath('.//ignore_js_op'))    imgs = driver.find_elements_by_xpath('.//ignore_js_op/img') # 找到相应的标签。    for img in imgs:        img_url = img.get_attribute('src')# 打印出属性为『src』的内容        print img_url        save_img(img_url)       if __name__ == '__main__':    # save_img(dabaiURL)    iter_img_page(dabaiPageURL)



附大白照片



0 0
原创粉丝点击