网上有许多爬取淘宝淘女郎的代码,发现有的都不可用,就自己改写了一个,当前可用日期为2017.07.30
前提
chromedriver.exe(本文用的是2.30,有两种使用方式,一种是直接绝对路径引用(本文使用的方式),一种是配置环境变量),谷歌浏览器的版本(版本 60.0.3112.78(正式版本) 这个需要和chromedriver.exe版本匹配),python3.6
如何查看该用哪个版本的chromedriver,先看谷歌浏览器的版—右上角–帮助–关于Google chrome 查看版本
主要遇到的问题
1,在写的时间发现https://mm.taobao.com/json/request_top_list.htm点击其中的头像有时跳到个人中心,有时跳到登录页面
解决方案:点击每个人的名字,跳到个人信息,获取其中的 域名地址://mm.taobao.com/tyy6160
造成的问题,有的淘女郎没有--- 域名地址
2,页面的延迟加载,否则获取的页面代码不完整
解决方案:selenium
代码
说这么多没用的,直接上代码
tool.py
#!/user/bin/env python
# -*- coding: utf-8 -*-
import re
# 处理页面标签类
class Tool:
# 去除img标签,1-7位空格,
removeImg = re.compile('<img.*?>| {1,7}| ')
# 删除超链接标签
removeAddr = re.compile('<a.*?>|</a>')
# 把换行的标签换为\n
replaceLine = re.compile('<tr>|<div>|</div>|</p>')
# 将表格制表<td>替换为\t
replaceTD = re.compile('<td>')
# 将换行符或双换行符替换为\n
replaceBR = re.compile('<br><br>|<br>')
# 将其余标签剔除
removeExtraTag = re.compile('<.*?>')
# 将多行空行删除
removeNoneLine = re.compile('\n+')
def replace(self, x):
x = re.sub(self.removeImg, "", x)
x = re.sub(self.removeAddr, "", x)
x = re.sub(self.replaceLine, "\n", x)
x = re.sub(self.replaceTD, "\t", x)
x = re.sub(self.replaceBR, "\n", x)
x = re.sub(self.removeExtraTag, "", x)
x = re.sub(self.removeNoneLine, "\n", x)
# strip()将前后多余内容删除
return x.strip()
spider.py
#!/user/bin/env python
# -*- coding: utf-8 -*-
import urllib.request
import urllib
import re
import tool
import os
from selenium import webdriver
from time import sleep
from bs4 import BeautifulSoup
# 抓取MM
class Spider:
# 页面初始化
def __init__(self):
self.siteURL = 'https://mm.taobao.com/json/request_top_list.htm'
self.tool = tool.Tool()
# 获取索引页面的内容
def getPage(self, pageIndex):
url = self.siteURL + "?page=" + str(pageIndex)
response = urllib.request.urlopen(url)
return response.read().decode('gbk')
# 获取索引界面所有MM的信息,list格式
def getContents(self, pageIndex):
page = self.getPage(pageIndex)
pattern = re.compile(
'<div class="list-item".*?pic-word.*?<img src="(.*?)".*?<a class="lady-name".*? href="(.*?)".*?>(.*?)</a>.*?<strong>(.*?)</strong>.*?<span>(.*?)</span>',
re.S)
items = re.findall(pattern, page)
contents = []
for item in items:
contents.append([item[0], item[1], item[2], item[3], item[4]])
return contents
# 获取MM个人详情页面
def getDetailPage(self, infoURL):
try:
#引用chromedriver.exe(可以设置到环境变量中)
path = "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"
driver = webdriver.Chrome(executable_path=path)
driver.get(infoURL)
sleep(2) # 强制等待5秒再执行下一步
soup = BeautifulSoup(driver.page_source, 'html.parser')
personUrl = soup.find('div', 'mm-p-info mm-p-domain-info')
realurl = personUrl.span.text
realPage = urllib.request.urlopen("https:" + realurl)
pageCode = realPage.read().decode('gbk')
except Exception as err:
return 0
return pageCode
# 获取个人文字简介
def getBrief(self, page):
pattern = re.compile('<div class="mm-p-info mm-p-domain-info".*?<span>(.*?)</span>', re.S)
result = re.search(pattern, page)
return self.tool.replace(result.group(1))
def getRealUrlPage(self,page):
#引用chromedriver.exe(可以设置到环境变量中)
path = "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"
driver = webdriver.Chrome(executable_path=path)
driver.get('https://mm.taobao.com/self/model_info.htm?user_id=687471686&is_coment=false')
sleep(2) # 强制等待5秒再执行下一步
soup = BeautifulSoup(driver.page_source, 'html.parser')
personUrl = soup.find('div', 'mm-p-info mm-p-domain-info')
realurl = personUrl.span.text
realPage = urllib.request.urlopen("https:" + realurl)
# print(realPage)
sp = BeautifulSoup(realPage, 'html.parser')
# 获取页面所有图片
def getAllImg(self, page):
pattern = re.compile('<div class="mm-aixiu-content".*?>(.*?)<!--', re.S)
# 个人信息页面所有代码
content = re.search(pattern, page)
# 从代码中提取图片
patternImg = re.compile('<img.*?src="(.*?)"', re.S)
images = re.findall(patternImg, content.group(1))
return images
# 保存多张写真图片
def saveImgs(self, images, name):
number = 1
print(u"发现", name, u"共有", len(images), u"张照片")
for imageURL in images:
splitPath = imageURL.split('.')
fTail = splitPath.pop()
if len(fTail) > 3:
fTail = "jpg"
fileName = name + "/" + str(number) + "." + fTail
try:
self.saveImg(imageURL, fileName)
except Exception as err:
continue
number += 1
if number > 10:
break
# 保存头像
def saveIcon(self, iconURL, name):
splitPath = iconURL.split('.')
fTail = splitPath.pop()
fileName = name + "/icon." + fTail
self.saveImg(iconURL, fileName)
# 保存个人简介
def saveBrief(self, content, name):
fileName = name + "/" + name + ".txt"
f = open(fileName, "w+")
print(u"正在偷偷保存她的个人信息为", fileName)
aaaa = str(content.encode('utf-8'))
f.write(aaaa)
# 传入图片地址,文件名,保存单张图片
def saveImg(self, imageURL, fileName):
print("输出url地址 "+imageURL)
u = urllib.request.urlopen("https:"+imageURL)
data = u.read()
f = open(fileName, 'wb')
f.write(data)
print(u"正在悄悄保存她的一张图片为", fileName)
f.close()
# 创建新目录
def mkdir(self, path):
path = path.strip()
# 判断路径是否存在
# 存在 True
# 不存在 False
isExists = os.path.exists(path)
# 判断结果
if not isExists:
# 如果不存在则创建目录
print(u"偷偷新建了名字叫做", path, u'的文件夹')
# 创建目录操作函数
os.makedirs(path)
return True
else:
# 如果目录存在则不创建,并提示目录已存在
print(u"名为", path, '的文件夹已经创建成功')
return False
# 将一页淘宝MM的信息保存起来
def savePageInfo(self, pageIndex):
# 获取第一页淘宝MM列表
contents = self.getContents(pageIndex)
for item in contents:
# item[0]个人详情URL,item[1]头像URL,item[2]姓名,item[3]年龄,item[4]居住地
print(u"发现一位模特,名字叫", item[2], u"芳龄", item[3], u",她在", item[4])
print(u"正在偷偷地保存", item[2], "的信息")
print(u"又意外地发现她的个人地址是", item[0])
# 个人详情页面的URL
detailURL = item[1]
# 得到个人详情页面代码
detailPage = self.getDetailPage('https:'+detailURL+'&is_coment=false')
# 获取个人简介
# brief = self.getBrief(detailPage)
if(detailPage != 0):
# 获取所有图片列表
images = self.getAllImg(detailPage)
self.mkdir(item[2])
# 保存个人简介
# self.saveBrief(brief, item[2])
# 保存头像
self.saveIcon(item[0], item[2])
# 保存图片
self.saveImgs(images, item[2])
# 传入起止页码,获取MM图片
def savePagesInfo(self, start, end):
for i in range(start, end + 1):
print(u"正在偷偷寻找第", i, u"个地方,看看MM们在不在")
self.savePageInfo(i)
# 传入起止页码即可,在此传入了1,10,表示抓取第1到10页的MM
spider = Spider()
spider.savePagesInfo(1, 10)