import urllib.request #访问网页一定会用到的模块
import os #os模块是在当前文件夹下创建一个文件
def url_open(url):
req=urllib.request.Request(url)
req.add_header('User-Agent','Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36')
response=urllib.request.urlopen(url)#打开这个网页
html=response.read()
return html
def get_page(url):#这个模块用来打开链接
req=urllib.request.Request(url)
req.add_header('User-Agent','Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36')
response=urllib.request.urlopen(url)#打开这个网页
html=response.read().decode('utf-8')
#html.decode('utf-8')#打开网页后读取这个网页的内容,并解码
a= html.find("current-comment-page")+9 #查找图片所在的当前页
b =html.find(']',a)
return html[a:b]
def find_imgs(page_url):
url_open(url).decode('utf-8')
img_addrs=[]
a=html.find('img src=')
while a!=-1:
b=html.find('.jpg',a,a+255)#限定寻找的范围,找不到会返回-1
if b !=-1:
img_addrs.append(html[a:b])
else:
b=a+9
a=html.find('img src=',b)
return img_addrs
def save_imgs(folder,img_addrs):
for each in img_addrs:
filename=each.sprit('/')[-1]
with open(filename,'wb') as f:
imag=url_open(each)
f.write(img)
def savepic(folder='opq',pages=10):
os.mkdir(folder) #在当前文件夹下创建一个名为folder的文件;
os.chdir(folder) #把当前的工作目录切换到改文件夹里面
url='http://jandan.net/ooxx'
page_num=int(get_page(url))
for i in range(pages):
page_num -=1
page_url=url+'/page-'+str(page_num)+'#comments'#获得图片所在网站的地址
img_addrs=find_imgs(page_url)#将对应网页的图片放到一个列表里面
save_imgs(folder,img_addrs)#将列表里面的文件保存到指定文件夹
if __name__=='__main__':
savepic()
匹配IP地址的方法:IP为255内的数字
使用正则表达式来实现筛选,在编写复查程序查找符合条件的字符串的时候;
只需匹配字符串则用find函数
正则表达式是使用 re 模块:
该模块中的search函数;
re.search(r'fish','i love fish.com')
search()方法用于在字符串中搜索正则表达式模式第一次出现的位置;若不存在则返回None
第一个参数是要搜索的字符串或规则(使用原始字符串更方便);返回满足条件的字符串的位置;
用find方法的时候:
'i love fish.com'.find('fish')
返回下标的起始地址:7
通配符:* ?表示任何类型的字符
正则表达式的通配符为 . 可以匹配除了换行符之外的任何字符;
利用反斜杠来转义;
在正则表达式中:元字符是在表达式中能有其他含义的字符,如点号,反斜杠能剥夺这一功能;反斜杠也能使得普通字符拥有其他能力;如:
\d表示匹配数字
寻找IP:
但是这种方法过于繁琐
使用中括号来创建一个字符类,其含义为只要匹配这个字符类中的任意一个字符即为匹配成功;
匹配元音字母:
中括号里面的字符类也可以是一个范围,用 - 表示范围
限定重复匹配的次数可以用大括号来解决:
re.search(r'ab{3}c','abbbc')
表示大括号前的元素需要重复匹配的次数,即b需要重复匹配三次;如果字符串中元素多于需要匹配的次数,则不能匹配;
正则表达式匹配的是字符串,因此数字只有0-9的字符串;
[0-255]这个字符类表示范围为0-2 和5 的字符串即0 1 2 5
因此用正则表达式来匹配0-255的方法为:
在正则表达式中\d表示任何0-9的数字
采用分类讨论的思想:该语句的意思为,第一个数字如果未0或者1,则第二第三个数字可以是任何,或者第一个数字为2,第二个数字为0-4,则第三个数字可以为任何,或者前两个数字为25,第三个数字为0-5,其中|表示逻辑或
小括号表示将里面的元素作为一个整体:
'''常用的特殊符号,特殊符号由两部分组成,第一部分为元字符,第二部分为 \ +特殊符号
. 匹配除了换行符之外的任何字符
| 跟逻辑或一个意思,A|B表示匹配正则表达式A或者B '''
re.search(r"fish(c|d)",'fishc')#表示匹配fishc或者fishd
# ^ (脱字符)匹配输入字符串的开始位置
re.search(r"^fish(c|d)",'fishc') #能匹配
re.search(r"^fish(c|d)",'I fishc') #不能匹配,因为开始位置不匹配,而^限定了只能匹配开始位置
# $匹配输入字符串的结束位置
re.request(r"fish(c|d)$",'fishc')#可以匹配
re.request(r"fish(c|d)$",'fishc!') #不能匹配
'''
\ 1.将一个普通字符变成特殊字符,如\d表示匹配所有的二进制数字
2.解除原字符的特殊功能,如\. 表示匹配点号本身
3.引用序号对应的子组所匹配的字符串,子组的序号从0开始编号
'''
re.search(r"(fishc)\1",'i fishc !')#\1表示前面小括号里面的子组,因此对该内容复制了,匹配不成功
re.search(r"(fishc)\1",'i fishcfishc !')#可匹配
(fishc)\1 == fishcfishc
'''
[] 生成一个字符类,被它包围的字符会失去特殊功能,用来匹配其所包含的任意一个字符
- 如果出现在字符串中间表示字符范围描述;如果出现在首位则为普通含义
\ 特殊字符仅有\保留特殊含义,用于转义字符
^ 脱字符^如果出现在首位则表示匹配不包含其中的任意字符,就是取反的意思,取不存在于该字符类中的
元素其他位置为普通字符
'''
\. == [.]
re.findall(r'[a-z]','Fish')#找到匹配的元素并打包成列表后返回,输出结果为 ['i', 's', 'h']
{n,m}表示对大括号前的元素重复n~m次,大括号里面不能用空格,会被解析为正则表达式
* 表示匹配的子表达式0次或多次,等价于{0,},即0到正无穷次
+ 表示匹配的子表达式1次或多次,等价于{1,},即1到正无穷次
?表示匹配的子表达式0次或1次,等价于{0,1},即1到正无穷次 (推荐使用特殊符号而不是大括号里面的)
{m,n}
贪婪模式表示在条件合适的情况下尽可能多的取匹配;
该模式匹配了开头后一直搜索到结尾,然后再倒着往前确定结尾的字符串
非贪婪模式:启用方法为在表示重复的元字符后面加上一个 ?
.表示所有的元素,+表示1到正无穷,为表示重复的元字符
\+特殊字母构成的正则表达式中的特殊含义