空闲的时候随便找了一个网站练习一下爬虫,总结一下自己写爬虫遇到的知识点

实现的功能

抓取全站URL

获取CSS,JS, img等文件连接

获取文件名字

保存文件到本地

用到的模块

urllib

bs4

re

os

第一部分:抓取全站URL

先贴上代码

# 获取当前页面子网站子网站
def get_urls(url, baseurl, urls):
    with request.urlopen(url) as f:
        data = f.read().decode('utf-8')
        link = bs(data).find_all('a')
        for i in link:
            suffix = i.get('href')
            # 设置排除写入的子连接
            if suffix == '#' or suffix == '#carousel-example-generic' or 'javascript:void(0)' in suffix:
                continue
            else:
                # 构建urls
                childurl = baseurl + suffix
                if childurl not in urls:
                    urls.append(childurl)
# 获取整个网站URL
def getallUrl(url, baseurl, urls):
    get_urls(url, baseurl, urls)
    end = len(urls)
    start = 0
    while(True):
        if start == end:
            break
        for i in range(start, end):
            get_urls(urls[i], baseurl, urls)
            time.sleep(1)
        start = end
        end = len(urls)

通过urllib包中的request,调用urlopen对网站进行访问
首先从首页开始,首页里面一般包含各个子页面的URL,把抓取到的URL添加到一个列表里面
然后再读取这个列表的每个元素,依次进行访问,获取子页面上的url连接添加到列表。
感觉这样抓取整站URL不是很靠谱,有时间会完善下

第二部分:获取css,js,img的连接

先贴上代码

# 获取当前网页代码
    with request.urlopen(url) as f:
        html_source = f.read().decode()
# css,js,img正则表达式,以获取文件相对路径
        patterncss = '<link rel="stylesheet" href="(.*?)"'
        patternjs = '<script src="(.*?)"'
        patternimg = '<img src="(.*?)"'
        titleStr = re.compile(pattertitil
# 使用re模块通过正则规则获取相对路径
        cssHerf = re.compile(patterncss, re.S).findall(html_source)
        jsHref = re.compile(patternjs, re.S).findall(html_source)
        imgHref = re.compile(patternimg, re.S).findall(html_source)

然后基于网站地址 + Href即可获得各个文件的地址

第三部分:获取文件名字

这里其实用python的split()就可以解决,我作死用了一个早上去写正则,就写出了css的正则。
代码如下
path需提前传进来

# 获取css文件名并选择本地保存路径(使用了正则)
        patternCssTitle = '(/?.*?.css?)'
        filename = path + '\\' + re.compile(patternCssTitle, re.S).findall(url)[1][1:]
        # 使用split方法
        filename = path + '\\' + href[i].split('/')[-1]
# 获取js文件名并选择本地保存路径
        filename = path + '\\' + href[i].split('/')[-1]
# 获取img文件名并选择本地保存路径
        filename = path + '\\' + href[i].split('/')[-1]

第四部分:保存文件到本地

使用pythonIO进行读写操作,为防止出错采用了try..except..

# 保存html
        try:
            with open(filename, 'w') as f:
                f.write(html_source)
        except:
            print("文件无法保存,请检查参数配置")
            exit(1)
# 保存CSS文件
        try:
            with request.urlopen(url) as w:
                css_source = w.read().decode()
                with open(filename, 'w') as f:
                    f.write(css_source)
                print(re.compile(patternCssTitle, re.S).findall(url)[1][1:] + " css文件保存成功!")
                time.sleep(1)
        except:
            print("该" + re.compile(patternCssTitle, re.S).findall(url)[1][1:] + " css文件无法下载")
# 保存js文件
        try:
            with request.urlopen(url) as w:
                js_source = w.read().decode()
                with open(filename, 'w') as f:
                    f.write(js_source)
                print(href[i].split('/')[-1] + " js文件保存成功")
                time.sleep(1)
        except:
            print("该" + href[i].split('/')[-1] + " js文件无法下载")
            # 这里使用continue是因为遇到cdn的js文件报错没办法保存,直接跳过
            continue

在保存图像的时候我没有使用decode()

# 保存img文件
        try:
            with request.urlopen(url) as w:
                img_source = w.read()
                with open(filename, 'wb') as f:
                    f.write(img_source)
                print(href[i].split('/')[-1] + " 图像文件保存成功")
                time.sleep(1)
        except:
            print("该" + href[i].split('/')[-1] + " 图像无法下载")

采用with(),防止读写文件时没有关闭

其实还有另外一种方法获取文件和代码,从腾讯云上面看到的,但是我尝试了就打开了浏览器后面没有进行保存。
* 出处https://cloud.tencent.com/developer/ask/49008

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

br = webdriver.Firefox()
br.get('http://www.google.com/')

save_me = ActionChains(br).key_down(Keys.CONTROL)\
         .key_down('s').key_up(Keys.CONTROL).key_up('s')
save_me.perform()

 本文源码地址:https://github.com/gorquan/gzjianguang.git