关键字:正则表达式 python 爬虫

调试不易,老程序员恳请:转载请注明出处。  

近期由于搜集素材需求下载了一些图片。附代码如下,话先说好,如果读者需要使用,请节制好下载频率,被微信封号我不管哦。:)

下载资源首先从文件中获取,文件是文章的链接URL。

正则表达式分析文章,简单的写了几种图片方案。本程序前期主要用于下载公众号了,所以一开始的下载比较多的使用datasrc判断,微信以后可能也会改。没有使用selenium就已经完成下载了,以后再贴一个用selenium的。

代码的一些解释:

首先把html文档按照标签分解,没有按照soup的find直接搜索,因为我不确定微信的公众号网页是以什么方式嵌入的图片。有时候,编辑会使用<img class= ... data-type=... src=""...>来嵌入一个图片,有时候是src在前,<img class= ... src=""... data-type=...>

data-type这里是文件类型,可以由此判断文件的扩展名。

向文件logfile.log输出log,下载成功的链接在前面加succ字样,失败的链接在前面加fail字样。

# -*- coding: utf-8 -*-
"""
Created on Mon Dec 24 14:04:34 2018

@author: Thor
"""

#selenium爬取图片
#import sys
#from selenium import webdriver
import os
from datetime import datetime
from re import findall
import re
from pprint import pprint
from urllib.request import urlopen

def strIsNum(string):
    #全部是数字时返回True
    return re.match("[0-9]+$", string) != None


image_path = '.\\wechatimglu'

#print(os.curdir)
if not os.path.exists(image_path):
    #判断要放图片的目录是否存在:
    os.mkdir(image_path)
    print("true")

#把文件保存目录改为当前目录下面的image_path
try:
    os.chdir(image_path)
except Exception as e:
    print(e)
    print("Failed to change directory")

for root, dirs, files in os.walk("."):
    if root == ".":
#        print(root)
#        print(dirs)
#        print(files)
#获取image_path目录下的所有文件名,split和join用于将扩展名去掉。
        filelistWithoutExtName = [".".join(p.split(".")[:-1]) for p in files]

maxFileName = max(int(x) for x in filelistWithoutExtName if strIsNum(x) )
print(maxFileName)
while(True):
    try:
        print("please input your start index:")
        #读取并判断index是否在文件夹中已经存在,如果存在则返回此循环继续读取index
        strindex = input()
        jpgindex = int(strindex)
        filename = "%d.%s"%(jpgindex,"png")
        if not strindex in filelistWithoutExtName:
            #print(filelistWithoutExtName)
            print("the start index is:%d,press any key to run,or ctrl-c to exit."%jpgindex)
            tempchar = input()
            break #jpgindex can be converted into int
        else:
            print("The index has already existed, please change.\n\
                if you just enter, the index will start with %s"%maxFileName)
    except Exception as e:
        pass
#jpgindex = 161
urls = []
#website文件放在上一级目录里
with open("..\website.txt", "r") as filesource:
    for line in filesource.readlines():
        url = line.strip()
        urls.append(url)
        
print("Retrieving...")


for url in urls:
    #打开URL
    with urlopen(url) as fp:
        content = fp.read().decode("gbk",errors='ignore')   # 需要进行解码成字符串
        
    #print(content)
    
    #写URL日志
    with open("..\\filehtm.txt","w") as f:
        f.write(content)
        
    '''
    把文本按照标签分开,<html> </html>会被分到两个变量输入result
    再将结果输出到迭代器进行下载。
    '''
    resultDiv = findall("<(.+?)>", content)
    result = []
    for contentdiv in resultDiv:
        #pattern = 'data-src="(.+?)" data-type="jpeg" '
        pattern = 'data-src="(.+?)" data-type="(gif|png|jpeg|jpg)"'
        if re.search("data-type=\"(gif|png|jpeg|jpg)", contentdiv) != None:
            result += findall('data-src="(.+?)"', contentdiv)
        if re.search("data-src", contentdiv) == None:
            #没有找到数据 print("pppp",contentdiv)
            if re.search("img src=\"(.+?)\"",contentdiv) != None:
                result += [ "http:" + url for url in findall('img src="(.+?)"', contentdiv) if re.match("http", url) == None]
                result += findall('img src="(.+?)"', contentdiv)
            else:
                result += findall('img.+? src="(.+?)"', contentdiv)
                
        #pattern = 'data-type="png" data-w=".+?" data-src="(.+?)"'
        #pattern = 'data-type="jpeg|png".+?data-src="(.+?)"'
        #result = findall(pattern, content)

        pattern = 'img src="(.+?)" style'
        result += findall(pattern, contentdiv)
        if len(result) == 0:
            if re.search("data-src", contentdiv) != None:
                result+= findall('src="(.+?)"', contentdiv)
    
    pprint(result)
    
    '''结果输出到迭代器进行下载'''
    for index, item in enumerate(result,1):
        try:
            if type(item) is not str:
                item = item[0]
            data = urlopen(str(item)).read()
        except Exception as e:
            print(e)
            print(str(item))
            continue
        print('开始下载第%s 张图片: %s'%(index, item))
        #提取图片中的最后fmt字符 格式作为图片扩展名
        try:
            fixnameindex = item.index("fmt=")
        except Exception as e:
            fixnameindex = -1
        """x形如 ...fmt=png ...fmt=jpeg,index会取f所在的位置,
        所以下一句向后取4个位置(fmt=是4个字符),一直到最后一个字符,如果index取到了-1,
        就是说没有找到fmt=的字样,那么默认在后面加jpg的扩展名"""
        fixname = item[fixnameindex +4 : ] if fixnameindex != -1 else "jpg"                
        #文件名生成
        filename = "%d.%s"%(jpgindex,fixname)
        #f = open(str(jpgindex) + fixname, "wb")
        f = open(filename, "wb")
        jpgindex += 1
        f.write(data)
        f.close()
    filelog = open("logfile.log", "a+")
    if len(result) != 0:
        filelog.write("succ|%s|%s\n"%(str(datetime.now()),url))
    else:
        filelog.write("fail|%s|%s\n"%(str(datetime.now()),url))
    filelog.close()