最近简单的学了一下Python爬虫,决定来爬一下csdn受欢迎的博客对应的博主的头像。其部分受欢迎的博客截图如下:
基本思路是:先爬取http://blog.csdn.net/ranking.html对应的网页的代码,该网页上包含了文章周排行,博客周排行,受欢迎的博客内容。然后从爬取的页面中,用正则表达式找到受欢迎的博客对应的div代码,接着从该div中用正则表达式过滤出博文对应的博主的头像链接,最后根据图片链接将图片下载到本地。
其实现代码如下所示:
#author = liuwei date = 2017-08-15
#抓取csdn博客中受欢迎的博客的信息列表,链接为http://blog.csdn.net/ranking.html
from urllib import request
import re
#params:
# url:网页的链接
#return:
# html:网页的html代码
def getPage(url):
'''通过网页的url地址,获取网页代码'''
req = request.Request(url)
response = request.urlopen(req)
html = response.read().decode("utf-8")
return html
#params:
# content:div的内容
#return:
# divName:该div的内容
def getDivName(content):
'''获取div中的<h3>标签中的中文内容'''
regex = re.compile("(?<=<h3 class=\"rank_t\">).+?(?=</h3>)")
divName = regex.findall(content)
return divName
#params:
# html:网页的html代码
#return:
# div:受欢迎的博客对应的div的代码
def getPopular(html):
'''通过获取每个div中的<h3>标签的内容来匹配受欢迎的博客,挑选出该div'''
#抓取所有class="ranking ranking_min"的div内容
regex = re.compile("<div class=\"ranking ranking_min\">.+?<\/div>", re.S)
allDiv = regex.findall(html) #得到所有div
#然后筛选出<h3>标签为受欢迎的博客的div
for div in allDiv:
divName = getDivName(div)
if ''.join(divName) == "受欢迎的博客":
return div
#params:
# div:div的代码
#return:
# allImage:所有图片的链接
def getAllImageUrl(div):
'''获取最受欢迎div中所有的图片链接地址'''
regex = re.compile("(?<=<img src=\").+?(?=\")") #截取所有的图片链接地址
allImage = regex.findall(div)
return allImage
#params:
# imgUrl:图片的链接地址
def downloadImg(imgUrl):
'''通过图片的链接地址下载图片'''
#先为request添加上浏览器代理(本人使用的是Chrome浏览器),需要为每一张图片添加refer头参数,如果在header中添加referer属性,
#则会出现403错误,拒绝访问查看网页的F12工作台中的NetWork信息可以发现,referer的值就是你需要访问的图片的链接地址
#浏览器代理的信息
agent = ('User-Agent', 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36')
header = []
header.append(agent)
x = 1
for url in imgUrl: #遍历每一张图片链接
opener = request.build_opener()
refer = ('Referer', url) #为opener头部添加referer属性信息
header.append(refer)
opener.addheaders = header #添加头部信息,避免被反爬虫
request.install_opener(opener)
request.urlretrieve(url, "G:\\csdn\\" + str(x) + ".jpg") #下载图片,并保存到本地
x = x + 1
if __name__ == '__main__':
url = "http://blog.csdn.net/ranking.html"
html = getPage(url) #获得整个网页
divRes = getPopular(html) #获取受欢迎的博客对应的div
allImgUrl = getAllImageUrl(divRes) #过滤该div中的博主头像链接
downloadImg(allImgUrl) #将博主头像下载到本地
本人刚开始只是在request头部添加了代理信息,即User-Agent属性值,在爬取图片的时候被服务器给拒绝访问了,即触发了HTTP Error 403: Forbidden错误。本人直接用浏览器打开相应的图片链接,发现可以打开图片,于是便去查看request header部分,发现在header中需要referer属性值(这个是本人试了之后才知道需要添加上referer属性),这样才不会被拒绝。
request header截图如下:
代码运行效果图如下: