#!/usr/bin/env python2.7# encoding=utf-8"""
爬取豆瓣电影TOP250 - 完整示例代码
"""import codecsimport requestsfrom bs4 import BeautifulSoup
DOWNLOAD_URL = 'httn.com/top250/'def download_page(url):
return requests.get(url, headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36'
}).contentdef parse_html(html):
soup = BeautifulSoup(html)
movie_list_soup = soup.find('ol', attrs={'class': 'grid_view'})
movie_name_list = [] for movie_li in movie_list_soup.find_all('li'):
detail = movie_li.find('div', attrs={'class': 'hd'})
movie_name = detail.find('span', attrs={'class': 'title'}).getText()
movie_name_list.append(movie_name)
next_page = soup.find('span', attrs={'class': 'next'}).find('a') if next_page: return movie_name_list, DOWNLOAD_URL + next_page['href'] return movie_name_list, Nonedef main():
url = DOWNLOAD_URL with codecs.open('movies', 'wb', encoding='utf-8') as fp: while url:
html = download_page(url)
movies, url = parse_html(html)
fp.write(u'{movies}\n'.format(movies='\n'.join(movies)))if __name__ == '__main__':
main()12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
简单说明下,在目录下会生成一个文档存放电影名。python2
在开发者工具中观察到该请求的Status Code是302,Response Headers中Location是该预告片的真正地址(该地址是时间的函数,不唯一! 但测试表明不同时间生成的不同的地址都能下载该预告片!
存为字典,做个异常判断,如果含有这个key.就跳过。么有这个key就添加到dict中
看你爬什么咯?如果是网页,那就是页面代码;如果是制定内容,那爬取的时候就给定匹配的关键字,返回你指定的数据(字串,list,json都可以)
没有的事,如果是这样的话,百度,谷歌这些搜索引擎公司也是犯法的了。他们也是爬取别人的网站,获取信息,给用户用的。其实搜索引擎就是一种爬虫。
如果网站本身不做鉴别,网站会认为爬虫和一般的浏览器的行为是一样的。
1.观察url
首先观察一下网址的结构 http://movie.douban.com/top250?start=0filter=type= :
可以看到,问号?后有三个参数 start、filter、type,其中start代表页码,每页展示25部电影,0代表之一页,以此类推25代表第二页,50代表第三页...
filter顾名思义,是过滤已经看过的电影,filter和type在这里不重要,可以不管。
2.查看网页源代码
打开上面的网址,查看源代码,可以看到信息的展示结构如下:
1 ol class="96ed-362a-22c2-5ea2 grid_view" 2 li 3 div class="362a-22c2-5ea2-fcd3 item" 4 div class="22c2-5ea2-fcd3-a950 pic" 5 em class="3d70-6c8c-bbea-8123 "1/em 6 a href="http://movie.douban.com/subject/1292052/" 7 img alt="肖申克的救赎" src="http://img3.douban.com/view/movie_poster_cover/ipst/public/p480747492.jpg" class="6c8c-bbea-8123-f91d " 8 /a 9 /div10 div class="bbea-8123-f91d-5a95 info"11 div class="8123-f91d-5a95-0a41 hd"12 a href="http://movie.douban.com/subject/1292052/" class="f91d-5a95-0a41-ec8d "13 span class="5a95-0a41-ec8d-9d3b title"肖申克的救赎/span14 span class="0a41-ec8d-9d3b-0e45 title" / The Shawshank Redemption/span15 span class="ec8d-9d3b-0e45-d50f other" / 月黑高飞(港) / *** 1995(台)/span16 /a17 18 19 span class="9d3b-0e45-d50f-5e2a playable"[可播放]/span20 /div21 div class="0e45-d50f-5e2a-96ed bd"22 p class="d50f-5e2a-96ed-362a "23 导演: 弗兰克·德拉邦特 Frank Darabont 主演: 蒂姆·罗宾斯 Tim Robbins /...br24 1994 / 美国 / 犯罪 剧情25 /p26 27 28 div class="5e2a-96ed-362a-22c2 star"29 span class="96ed-362a-22c2-5ea2 rating5-t"em9.6/em/span30 span646374人评价/span31 /div32 33 p class="362a-22c2-5ea2-fcd3 quote"34 span class="22c2-5ea2-fcd3-a950 inq"希望让人自由。/span35 /p36 /div37 /div38 /div39 /li
其中em class="3d70-6c8c-bbea-8123 "1/em代表排名,span class="6c8c-bbea-8123-f91d title"肖申克的救赎/span代表电影名,其他信息的含义也很容易能看出来。
于是接下来可以写正则表达式:
1 pattern = re.compile(u'div.*?class="bbea-8123-f91d-5a95 item".*?div.*?class="8123-f91d-5a95-0a41 pic".*?' 2 + u'em.*?class="f91d-5a95-0a41-ec8d "(.*?)/em.*?' 3 + u'div.*?class="5a95-0a41-ec8d-9d3b info".*?span.*?class="0a41-ec8d-9d3b-0e45 title"(.*?)' 4 + u'/span.*?span.*?class="ec8d-9d3b-0e45-d50f title"(.*?)/span.*?' 5 + u'span.*?class="9d3b-0e45-d50f-5e2a other"(.*?)/span.*?/a.*?' 6 + u'div.*?class="0e45-d50f-5e2a-96ed bd".*?p.*?class="d50f-5e2a-96ed-362a ".*?' 7 + u'导演: (.*?) ' 8 + u'主演: (.*?)br' 9 + u'(.*?) / (.*?) / '10 + u'(.*?)/p'11 + u'.*?div.*?class="5e2a-96ed-362a-22c2 star".*?em(.*?)/em'12 + u'.*?span(.*?)人评价/span.*?p.*?class="96ed-362a-22c2-5ea2 quote".*?'13 + u'span.*?class="362a-22c2-5ea2-fcd3 inq"(.*?)/span.*?/p', re.S)
在此处flag参数re.S代表多行匹配。
3.使用面向对象的设计模式编码
代码如下:
1 # -*- coding:utf-8 -*- 2 __author__ = 'Jz' 3 import urllib2 4 import re 5 import sys 6 7 class MovieTop250: 8 def __init__(self): 9 #设置默认编码格式为utf-810 reload(sys)11 sys.setdefaultencoding('utf-8')12 self.start = 013 self.param = 'filter=type='14 self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64)'}15 self.movieList = []16 self.filePath = 'D:/coding_file/python_file/File/DoubanTop250.txt'17 18 def getPage(self):19 try:20 URL = 'http://movie.douban.com/top250?start=' + str(self.start)21 request = urllib2.Request(url = URL, headers = self.headers)22 response = urllib2.urlopen(request)23 page = response.read().decode('utf-8')24 pageNum = (self.start + 25)/2525 print '正在抓取第' + str(pageNum) + '页数据...' 26 self.start += 2527 return page28 except urllib2.URLError, e:29 if hasattr(e, 'reason'):30 print '抓取失败,具体原因:', e.reason31 32 def getMovie(self):33 pattern = re.compile(u'div.*?class="22c2-5ea2-fcd3-a950 item".*?div.*?class="3d70-6c8c-bbea-8123 pic".*?'34 + u'em.*?class="6c8c-bbea-8123-f91d "(.*?)/em.*?'35 + u'div.*?class="bbea-8123-f91d-5a95 info".*?span.*?class="8123-f91d-5a95-0a41 title"(.*?)'36 + u'/span.*?span.*?class="f91d-5a95-0a41-ec8d title"(.*?)/span.*?'37 + u'span.*?class="5a95-0a41-ec8d-9d3b other"(.*?)/span.*?/a.*?'38 + u'div.*?class="0a41-ec8d-9d3b-0e45 bd".*?p.*?class="ec8d-9d3b-0e45-d50f ".*?'39 + u'导演: (.*?) '40 + u'主演: (.*?)br'41 + u'(.*?) / (.*?) / '42 + u'(.*?)/p'43 + u'.*?div.*?class="9d3b-0e45-d50f-5e2a star".*?em(.*?)/em'44 + u'.*?span(.*?)人评价/span.*?p.*?class="0e45-d50f-5e2a-96ed quote".*?'45 + u'span.*?class="d50f-5e2a-96ed-362a inq"(.*?)/span.*?/p', re.S)46 while self.start = 225:47 page = self.getPage()48 movies = re.findall(pattern, page)49 for movie in movies:50 self.movieList.append([movie[0], movie[1], movie[2].lstrip(' / '),
51 movie[3].lstrip(' / '), movie[4],
52 movie[5], movie[6].lstrip(), movie[7], movie[8].rstrip(),53 movie[9], movie[10], movie[11]])54 55 def writeTxt(self):56 fileTop250 = open(self.filePath, 'w')57 try:58 for movie in self.movieList:59 fileTop250.write('电影排名:' + movie[0] + '\r\n')60 fileTop250.write('电影名称:' + movie[1] + '\r\n')61 fileTop250.write('外文名称:' + movie[2] + '\r\n')62 fileTop250.write('电影别名:' + movie[3] + '\r\n')63 fileTop250.write('导演姓名:' + movie[4] + '\r\n')64 fileTop250.write('参与主演:' + movie[5] + '\r\n')65 fileTop250.write('上映年份:' + movie[6] + '\r\n')66 fileTop250.write(' *** 国家/地区:' + movie[7] + '\r\n')67 fileTop250.write('电影类别:' + movie[8] + '\r\n')68 fileTop250.write('电影评分:' + movie[9] + '\r\n')69 fileTop250.write('参评人数:' + movie[10] + '\r\n')70 fileTop250.write('简短影评:' + movie[11] + '\r\n\r\n')71 print '文件写入成功...'72 finally:73 fileTop250.close()74 75 def main(self):76 print '正在从豆瓣电影Top250抓取数据...'77 self.getMovie()78 self.writeTxt()79 print '抓取完毕...'80 81 DouBanSpider = MovieTop250()82 DouBanSpider.main()
代码比较简单,最后将信息写入一个文件,没有什么需要解释的地方。
经测试可知上面的完整请求地址,完全可以作为该预告片的“地址”。
PS:在开发者工具中观察到该请求的Status Code是302,Response Headers中Location是该预告片的真正地址(该地址是时间的函数,不唯一!
但测试表明不同时间生成的不同的地址都能下载该预告片!唉,不细究了)。
数日前 安全脉搏播报了《MS14-068 Kerberos Domain Privilege Escalation》,安全运维和渗透师必关注的一个漏洞,该漏洞可能允许攻击者提升普通域用户账户为...
文章转载自:香港地产资讯网 马鞍山云海备7款户型 1房380呎起 圣诞前上载楼书 冀农曆年前开售 新地马鞍山云海公布项目资料,发展商指,项目最快圣诞节及新年前与同系沙田九肚山云端双管齐发。 新...
最近玩蚂蚁庄园这个游戏的玩家都在问,游戏里面的9月28日每日一题问题答案是什么,今天的问题是企鹅们行走时为什么经常排成一列纵队答案是什么?大家都知道这道题的答案吗?小编我特意整理了相关的资讯,下面就是...
1416号台风凤凰的起始点和经过点——发布时间中心经度中心纬度中心气压最大风速台风等级2014-09-2321:00E:122.4°N:32.2°995hPa。 “凤凰”将以每小时20-25公里的速度...
我想同步接收我妻子的微信聊天记录可以吗? 婚姻期间,如果丈夫在婚姻中出轨,将夫妻共同财产秘密捐献给情人,妻子能追回吗? 近日,利川市法院审结了一起因婚姻不忠引发不当得利纠纷案。 基本|案例。...
什么牌子护肤品比较好?知名大牌化妆品明星产品点评之六 二十一、雪花秀明星产品 1、雪花秀采淡致美气垫粉底液:perfect!粉盒外形很漂亮,比较复古的感觉,做工也比较精致,总之外貌党非常喜欢。...