一、介绍
用python处理二进制文件的事情做的比较少,虽然之前有写过分析Ajax抓取今日头条街拍美图,但那个爬虫重在分析Ajax,并没有提到文件路径和文件命名,所以就有了这个爬虫
二、流程
流程一般化,没什么特别的,这里就不说了
---------------------------17/8/25第一次更新:关于文件名语法错误
- 当文件名中含@等特殊字符串时,文件名的字符串长度会超级超级长,会造成文件名语法错误这个问题我一开始是这样解决的:
if len(title)>20: #有些表情包的标题含特殊字符,例如@,这个时候文件夹名称会超长,导致程序报错
title =title[:3]
else:
title=title #虽然解决了问题,但也使得文件名不齐全
- 当文件名以?等标点符号结尾时,会造成文件名语法错误,这个问题是皮皮哥运行的时候发现的,所以用python删除标点符号,这个想法就冒出来了,在网上查到两种方法:translate()和正则,translate我写的没有解决问题,这里我就用正则,一般我们用正则得到的是一个列表,那样显然不符合我们的要求,所以我们要这样写:
import re
l='你知道@不>大,记得?'
m=' '.join(re.findall(u'[\u4e00-\u9fff]+', l))
print(type(m))
m=m.replace(' ', '') #这里再用replace把空格去掉
print(m)
a=re.findall(u'[\u4e00-\u9fff]+', l)
print(type(a))
print(a)
运行结果:
F:\Anaconda3\python.exe E:/Pycharm文件存储位置/day33/2.py
<class 'str'>
你知道不大记得
<class 'list'>
['你知道', '不', '大', '记得']
Process finished with exit code 0
- strip()函数原型
有人说空格可以直接用strip()函数啊,这里我再补充一点关于strip()函数的用法
声明:s为字符串,rm为要删除的字符序列
s.strip(rm) 删除s字符串中开头、结尾处,位于 rm删除序列的字符
s.lstrip(rm) 删除s字符串中开头处,位于 rm删除序列的字符
s.rstrip(rm) 删除s字符串中结尾处,位于 rm删除序列的字符
1. 当rm为空时,默认删除空白符(包括'\n', '\r', '\t', ' ')
>>> a = ' 123'
>>> a.strip()
'123'
>>> a='\t\tabc'
'abc'
>>> a = 'sdff\r\n'
>>> a.strip()
'sdff'
2.这里的rm删除序列是只要边(开头或结尾)上的字符在删除序列内,就删除掉。
>>> a = '123abc'
>>> a.strip('21')
'3abc' 结果是一样的
>>> a.strip('12')
'3abc'
三、代码
import requests
from bs4 import BeautifulSoup
import os
import re
from requests.exceptions import RequestException
base_url='https://www.doutula.com/article/list/?page='
def get_page_index(url):
try:
response = requests.get(url)
if response.status_code == 200:
return response.text
return None
except RequestException:
print('请求索引页出错')
return None
def parse_the_index(html):
pattern1 = re.compile('random_title">(.*?)<div class="date', re.S)
titles = re.findall(pattern1, str(html))
pattern2 = re.compile('(https?://www.doutula.com/article/detail/\d+)', re.S) #有些是http://,有些是https://
items = re.findall(pattern2, str(html))
for i in range(10): #每页10套表情包,这个是固定的
try: #中途报错加上去的
if get_page_index(items[i]):
html=get_page_index(items[i])
picture_url=get_picture_url(html)
for url in picture_url:
if 'http' in url:
url=url
else:
url=str('http:')+url
mkdir(titles[i], url)
except IndexError: #这个错误是有些图片在html中抓取的url没有http:造成的,后面错误被我补好了,留着它也没事
print('这页网页结构不一样,pass')
def download(url): #下载图片
response = requests.get(url)
p=response.content #返回二进制格式
name = url[-9:-4]
try:
f = open(name + '.jpg', 'ab')
f.write(p)
f.close()
except FileNotFoundError: #这个错误在中途遇到一次,没搞懂它为什么报错
print('储存文件失败')
def mkdir(title,url):
'''if len(title)>20:
title =title[:3]
else:
title=title'''
title = ' '.join(re.findall(u'[\u4e00-\u9fff]+', title))
title = title.replace(' ', '')
isExists = os.path.exists(os.path.join("D:\doutu", title))
if not isExists:
print(u'建了一个名字叫做', title, u'的文件夹!')
os.makedirs(os.path.join("D:\doutu", title)) #返回这个文件夹
else:
pass
os.chdir(os.path.join("D:\doutu", title))
download(url)
return True
def get_picture_url(html): #获得详情页里表情包图片的url
pattern = re.compile('img src="(.*?)" alt=', re.S)
picture_url = re.findall(pattern, str(html))
return picture_url
def the_sum(): #获取总页数
html = get_page_index(base_url)
soup = BeautifulSoup(html,'lxml')
sum = soup.find_all("a", href="/article/list/?page=510")
sum=int(sum[0].get_text()) #使用选择器获得的是一个列表,get_text()只能对列表里的元素使用
return sum
def main():
sum=the_sum()
for i in range(1,sum+1):
print('正在下载第%d页表情包'%i)
url = base_url+str(i)
html = get_page_index(url)
parse_the_index(html)
if __name__ == '__main__':
main()
四、最后得到的表情包
五、总结
1.正则虽然好用,但稍显复杂,要好好看看选择器的知识了
2.调试程序的时候好好利用try:...