第一弹
人生苦短
导语
这次爬取的是妹子图(meizitu.com),算是一个非常适合新手的网站。
完成这次的项目主要用到以下几个库:
import requests
from multiprocessing import Pool
from requests.exceptions import RequestException
import sys
from bs4 import BeautifulSoup
import os
from hashlib import md5
import pymongo
主要实现了图集、图片链接存储到mongoDB数据库,下载图片到本地,图片去重。
分析目标站
访问网站就可以看到很多让人热血贲张的套图了,首先我们翻到最下面,寻找爬虫的入口,好的爬虫入口往往可以让你事半功倍。
翻到网站的最后可以看到翻页的按钮,我们通过点击不同的页面来查看网页链接是否有什么变化。
可以看到点击页面地址栏中链接中的数字在不断增加,例如下面是第五页的链接:
http://www.meizitu.com/a/more_5.html,所以我们可以根据这个链接构建我们请求的URL。
# 构建每一页的链接
def get_index_page(page_number):
url = 'http://www.meizitu.com/a/more_{}.html' .format(page_number)
try:
reponse = requests.get(url, headers=headers)
reponse.encoding = reponse.apparent_encoding
if reponse.status_code == 200:
return reponse.text
return None
except RequestException:
print('请求列表页错误')
return None
分析图集列表页面
寻找完入口URL之后我们开始分析单个图集列表页面,先拿到单个页面所有图集的链接,我们可以使用bs4直接解析出来,可以使用浏览器直接得到要采集元素的信息。
图集详情中每张图片的链接的解析方法和这个是一样的,就不再赘述。
# 解析列表页,把每一页中的单个图集链接解析出来
def parse_index_page(html):
url = []
soup = BeautifulSoup(html, 'lxml')
url_list = soup.select('图第三点中复制的信息')
length = len(url_list)
for i in range(length):
url = url + [url_list[i].attrs["href"]]
return url
下载图片至本地并去重
下载图片其实就是将要存储的文件以二进制流的方式保存下来。
重点还是放在去重上,这里使用了hashlib模块,因为每一张图片的MD5值都是唯一的,如果MD5值相同就代表是同一张图片我们就不做下载。
# 下载图片
def download_image(url):
print('正在下载', url)
try:
reponse = requests.get(url, headers=headers)
if reponse.status_code == 200:
# print(reponse.text)
save_image(reponse.content)
return None
except RequestException:
print('请求下载图片错误', url)
return None
# 保存图片,校验去重
def save_image(content):
file_path = '{0}/{1}.{2}'.format(os.getcwd(), md5(content).hexdigest(), 'jpg')
if not os.path.exists(file_path):
with open(file_path, 'wb') as f:
f.write(content)
f.close()
存储到mongoDB数据库
首先你要安装好mongoDB数据库(废话),接下来就是基本的mongoDB操作。
# 保存到mongoDB数据库
def save_to_mongo(result):
if db[MONGO_TABLE].insert(result):
print('存储到mongoDB成功', result)
return True
return False
尾言
本来还用了多进程,但是爬取到50几页的时候就卡住不动了,个人感觉是因为链接的获取进程没赶上下载的进程,当然这只是我的一家之言(其实是我瞎编的,hhhhh)
经过一个小时的奋战,成果如下: 爬取这个网站的时候还是遇到了一点下问题是之前自学的时候没有注意的在这里做一个标注:
1.获取网页内容的时候网页中文显示乱码,可以通过获取网站的编码对自己获取的网站内容再编译来解决。
reponse.encoding = reponse.apparent_encoding
2.多进程并不是什么情况下用都是利好的。 喜欢此内容的人还喜欢