爬虫模块创建完成后,仅仅拥有了网页下载功能,接下来就需要进行网页数据的提取。
Scrapy有自己的一套数据提取机制,叫做选择器(selector),是通过特定的XPath或者CSS表达式来选择HTML文件中的某个部分。不过我之前主要使用的是BeautifulSoup包来解析网页,所以这里还继续用了BeautifulSoup,感兴趣的同学可以去找文章看看XPath的方法。
页面数据的提取还是在parse方法中完成,首先我们看一下豆瓣电影网页的html文件,https://movie.douban.com/。发现主页有正在热映电影的简要介绍,而如果想得到比较多的影片信息的介绍,则需要打开每一个具体的影片页面,获得更多的信息。这里发现主页会有URL地址,在a标签下,οnclick="moreurl(this,{from:'mv_a_tl'})"中。
首先获取页面,然后用BeautifulSoup方法解析页面。通过find_all找到页面中含有电影URL的标签,并get到“href”属性,就得到了具体一部电影的URL地址,然后加入到full_urls中。然后再从full_urls中取出地址,打开每部影片,从里面获取到标题,年份,导演,主演等详细的影片资料。
具体代码如下:
def parse(self,response):
data = response.body
soup = BeautifulSoup(data,'lxml')
for url_list in soup.find_all(οnclick="moreurl(this, {from:'mv_a_tl'})"):
url = url_list.get('href')
full_urls.append(url)
for a in full_urls:
page = urllib.request.urlopen(a)
opp = BeautifulSoup(page,'lxml')
# 获取标题
title = opp.find(property="v:itemreviewed").string
year = opp.find(class_='year').string
pl = opp.find(id="info")
# 获取导演
directer = []
for a in pl.find_all(rel="v:directedBy"):
t = a.string
directer.append(t)
# 获取编剧信息
a = pl.find_all(class_='attrs')
global scenarist
if len(a)<2:#判断列表里面是否有第2条的编剧信息
print(None)
else:
b = a[1]
dr = re.compile("<[^>]*?>|\[|\]",re.S)
dd = dr.sub('',str(b))
scenarist = []
scenarist = dd.split('/') # 字符串转成数组
# 获取演员信息
actor = []
a = pl.find(class_='actor')
if a == None:
print(None)
else:
for b in a.find_all('a'):
t = b.string
actor.append(t)
# 获取地区
dr = re.compile("<[^>]*?>|\[|\]",re.S)
area_pattern = re.compile("(?<=制片国家/地区:)[\w\W]*?(?=<br/>)",re.S)
a = area_pattern.search(str(pl))
if a == None:
print('无')
else:
a = a.group(0)
b = re.sub('\s', '', dr.sub('', a))
area = []
area = b.split('/')
里面有几个要注意的地方:
1、由于有些资料会存在空缺,所以要判断是否有内容,否则会返回“NoneType”,导致报错。
2、有些资料会有多条,所以用数组的方式进行保存。
3、一些需要用正则表达式进行判断提取,然后再进行去标签处理。