Python爬虫学习(五)爬取电影排行榜及其图片
2017-08-19 本文已影响676人
弃用中
这节我们演示一个实战例子,用于巩固一下之前学到的知识。
话不多说,直接开始。
确定目标
电影排行榜那么多,到底爬取哪个呢?
嘿嘿,随便找到了一个:http://dianying.2345.com/top/

貌似只有50部,没关系,做个小练习足矣!
分析网页
在Chrome浏览器打开网站,查看网页的结构,

我们可以发现,图片信息包含在<div class="pic">……</div>
中,而文本信息包含在<div class="txt">……</div>
中,接下来就开始动手写代码咯!
写代码
先获取到网页源码,并查看一下:

报错了,原因是 页面源码的编码方式和我们用decode
的解码方式对不上,怎么办呢?有好多方法可以解决这个问题:
- 在浏览器中查看网页编码方式,修改
decode
- 使用
chardet
库查看网页编码方式,修改decode
- 等等
这里,我们使用第二种,如图所示:

原来网页的编码方式是GB2312。
知道这个就好办了,我们调整一下代码:
import urllib.request
import re
import random
from urllib.request import Request
import chardet
# 修改一下请求头,伪装成浏览器
def get_page(url):
user_agent = [
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
]
headers = {'User-Agent':random.choice(user_agent)}
requ = Request(url,headers=headers)
page = urllib.request.urlopen(requ).read()
page = page.decode('gb2312')
return page
url = 'http://dianying.2345.com/top/'
get_page(url)
运行结果:

神马?怎么还有编码的问题!
我们查看网页源码,

发现并编码方式并没有错,那是怎么回事呢?让我们一探究竟。
根据报错的提示,错误出现在103处,那我们就先不解码,把原始的bytes
输出来看一下,

顺利的找到了出错的地方,并且可以看出在<title>
标签中,后面还有数字2345,于是我们可以可以猜想,错误应该就出现在这几个字中:

于是,我们可以到网站:http://www.qqxiuzi.cn/bianma/zifuji.php,验证一把,结果如下:

瞬间懂了,原来GB2312中并没有“–”这个字符,怪不得会出错!同时发现,GBK有对其编码,于是我们选用GBK解码。

nice!
提取数据
def parse_page(page,regexExpr):
pattern = re.compile(regexExpr,re.S)
results = re.findall(pattern,page)
return results
regexExpr = '<div class="txt">.*?<span class="sTit">.*?<a.*?>(.*?)</a>.*?<p class="pActor">(.*?)</p>.*?<p class="pTxt.*?>(.*?)<.*?</div>'
txts = parse_page(page,regexExpr)
for txt in txts:
print(txt)
输出内容不够美观,可以自己调整:

那么图片呢?
def parse_page(page,regexExpr):
pattern = re.compile(regexExpr,re.S)
results = re.findall(pattern,page)
return results
regexExpr = '<div class="txt">.*?<span class="sTit">.*?<a.*?>(.*?)</a>.*?<p class="pActor">(.*?)</p>.*?<p class="pTxt.*?>(.*?)<.*?</div>'
txts = parse_page(page,regexExpr)
regexExpr = '<div class="pic".*?<img.*?src="(.*?)"'
pics = parse_page(page,regexExpr)
for i in range(len(pics)):
# 下载图片
with open('Images/'+txts[i][0]+'.png','wb') as f:
f.write(urllib.request.urlopen(pics[i]).read())
结果如下:

最后,你可以对代码进行改进!
以上。
