Scrapy框架抓取豆瓣电影的小爬虫学习日记(二)

来源:互联网 发布:mac的发布时间 编辑:程序博客网 时间:2024/04/28 10:58

爬虫模块创建完成后,仅仅拥有了网页下载功能,接下来就需要进行网页数据的提取。

Scrapy有自己的一套数据提取机制,叫做选择器(selector),是通过特定的XPath或者CSS表达式来选择HTML文件中的某个部分。不过我之前主要使用的是BeautifulSoup包来解析网页,所以这里还继续用了BeautifulSoup,感兴趣的同学可以去找文章看看XPath的方法。

页面数据的提取还是在parse方法中完成,首先我们看一下豆瓣电影网页的html文件,https://movie.douban.com/。发现主页有正在热映电影的简要介绍,而如果想得到比较多的影片信息的介绍,则需要打开每一个具体的影片页面,获得更多的信息。这里发现主页会有URL地址,在a标签下,onclick="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(onclick="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、一些需要用正则表达式进行判断提取,然后再进行去标签处理。

阅读全文
0 0
原创粉丝点击