在知乎看见有不少人利用python下载了pixabay的图片,发现pixabay上的图片质量确实不错,自己也试着也写了一个小爬虫,权当练手。仅抓取照片的内容
系统:win7 64bit 工具:python 2.7.12 IDE:pycharm 6.3
以第2页的url为例: 总页数:165 每页图片量:60 获取方法:GET https://pixabay.com/zh/editors_choice/?media_type=photo&pagi=2
看下“?”后的参数: media_type :类型,这里抓取的图片,所以为photo pagi:对应为页码,改动该参数实现对各页的访问
关于网页的请求,我们可以构造一个循环遍历访问。
看下可抓取的字段
图片网址作者名点赞数收藏量评论数右键选择核查元素,查看源代码中数据的位置
网页内容解析 根据源码公布的数据配置相应的正则表达式,此处也可以用xpath、Beautifulsoup进行数据提取:
re.compile(r'srcset="(?P<url>\S+).*?<em.*?</i>(?P<zz>.*?)</em.*?<em.*?</i>(?P<sc>.*?)</em.*?<em.*?</i>(?P<pj>.*?)</em.*?<a.*?>(?P<author>.*?)</a',re.S)连接mysql数据库 通过MySQLdb模块连接mysql数据库,进行操作,定义一个datasave函数,详见代码:
def datasave(self): print u'开始连接mysql数据库' try: conn = MySQLdb.connect(host='localhost',port=3306,user='root',passwd='',db='python_test',charset='utf8') #获取操作游标 cur = conn.cursor() cur.execute('DROP TABLE IF EXISTS PIXABAY') sql='''CREATE TABLE PIXABAY( URL VARCHAR(200) NOT NULL, ZCOUNTS INT , SCOUNTS INT, PJCOUNTS INT, AUTHER VARCHAR(200)) ''' cur.execute(sql) print u'数据表已经创建,可以开始导入数据' if len(self.data)!=0: for data in self.data: print data['url'], data['zcounts'], data['scounts'], data['pjcounts'],data['auther'] cur.execute("INSERT INTO PIXABAY(URL,ZCOUNTS,SCOUNTS,PJCOUNTS,AUTHER) VALUES(%s,%s,%s,%s,%s)",(data['url'],data['zcounts'],data['scounts'],data['pjcounts'],data['auther'])) conn.commit() cur.close() conn.close() print u'数据已经全部插入库' except Exception,e: print u"错误原因",e1、程序运行起来看着还不错,一页60个图片,。当然,在刚开始运行并不是那么顺利,报出了不少异常。这些异常稍候总结。 2、运行完,查看下mysql中的数据量,共抓到9780个记录(少抓了一页,网站共有165页,我代码中的页数只抓到164页,最后一页没有抓),前4行记录的结果基本满足抓取的要求
3、统计下所抓取的数据 关于图片作者的top10排名 第一名共分享了489张图片,前三名分享的图片量相差大概在100左右,排名越向后,差距越小。
看下图片量top10的点赞量情况 分享量第一的PublicDomainPictures,点赞量当之无愧的第一,不仅量多,质量也是棒棒哒。但往下看,差异化就很明显了。分享量排名第7的Unsplash点赞量排名第三,看来分享的都是精品【微笑】。
按点赞量排名查看
按分享量排名查看点击量
还可以从收藏量、时间(网址中有)、评论量等维度进行分析,这里就不展开啦
以下是完整代码:
# -*- coding:utf-8 -*- import re import MySQLdb from lxml import etree import requests class pixabayspide(): def __init__(self): self.data = [] def geturls(self,url): #构造头部 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64)'} try: html = requests.get(url,headers=headers) html_doc = html.content return html_doc #返回源代码 except Exception ,e: print u"连接网页失败,错误原因", e print u"%s爬取异常,请核实" %url def htmlparse(self,page): #正则获取网页数据 patent = re.compile(r'srcset="(?P<url>\S+).*?<em.*?</i>(?P<zz>.*?)</em.*?<em.*?</i>(?P<sc>.*?)</em.*?<em.*?</i>(?P<pj>.*?)</em.*?<a.*?>(?P<author>.*?)</a',re.S) html_page = patent.findall(page) for html_doc in html_page: datadic = {} datadic['url'] = html_doc[0].replace('__340', '_960_720') #转换下图片像素,参考知乎崔斯特[微笑] datadic['zcounts'] = int(html_doc[1].strip()) datadic['scounts'] = int(html_doc[2].strip()) datadic['pjcounts'] = int(html_doc[3].strip()) datadic['auther'] = html_doc[4] self.data.append(datadic) print u'已经抓取%d个记录' %len(self.data) # for data in self.data: # print data['url'], data['zcounts'], data['scounts'], data['pjcounts'] def datasave(self): print u'开始连接mysql数据库' try: conn = MySQLdb.connect(host='localhost',port=3306,user='root',passwd='',db='python_test',charset='utf8') #获取操作游标 cur = conn.cursor() cur.execute('DROP TABLE IF EXISTS PIXABAY') sql='''CREATE TABLE PIXABAY( URL VARCHAR(200) NOT NULL, ZCOUNTS INT , SCOUNTS INT, PJCOUNTS INT, AUTHER VARCHAR(200)) ''' cur.execute(sql) print u'数据表已经创建,可以开始导入数据' if len(self.data)!=0: for data in self.data: # print data['url'], data['zcounts'], data['scounts'], data['pjcounts'],data['auther'] cur.execute("INSERT INTO PIXABAY(URL,ZCOUNTS,SCOUNTS,PJCOUNTS,AUTHER) VALUES(%s,%s,%s,%s,%s)",(data['url'],data['zcounts'],data['scounts'],data['pjcounts'],data['auther'])) conn.commit() cur.close() conn.close() print u'数据已经全部插入库' except Exception,e: print u"错误原因",e if __name__=='__main__': spide = pixabayspide() for i in range(1,165): url = 'https://pixabay.com/zh/editors_choice/'+'?media_type=photo&pagi='+str(i) page = spide.geturls(url) spide.htmlparse(page) print '已经完成第%d页数据的抓取' % i spide.datasave()最后希望对看到此处的你有所帮助【微笑】