利用python抓取豆瓣top500的电影

 前几天突然心血来潮想写一个爬虫,所以一开始写了一个抓取时光网数据的爬虫,主要用了beautifulsoup基本命令进行数据抓取,主要代码如下(具体代码说明包含在代码内部,在此就不细说了):

# -*- coding: utf-8 -*-
"""
Created on Thu Jan 18 14:37:37 2018

@author: cxoke
功能:抓取时光网top100的电影名字,导演。类型等
"""


# -*- coding:UTF-8 -*-
from bs4 import BeautifulSoup
import requests

if __name__ == '__main__':
    name=[]
    director=[]
    types=[]
    star=[]
    for i in range(2,11):
        url = 'http://www.mtime.com/top/movie/top100/index-{}.html'.format(str(i))
       #实现翻页功能,进行多页抓取
    
        headers = {
            "User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
            }#模拟浏览器进行抓取,防止网站反爬虫
        req = requests.get(url = url,headers = headers)
        req.encoding = 'utf-8'
        html = req.text
        bf = BeautifulSoup(html, 'lxml')
        daoyans=bf.select('.mov_con h2')#寻找属性为“mov_con”并且定位到位h2的标签抓取里面的内容

        for each in daoyans:
            name.append(each.text)
        daoyans=bf.select('.mov_con p')
        for daoyan in daoyans:
            if'导演:' in daoyan.text:
                director.append(daoyan.text)
            if'主演: ' in daoyan.text:
                star.append(daoyan.text)
            if'类型:' in daoyan.text:
                types.append(daoyan.text)
   
#将抓取的数据写入csv         
import pandas as pd
    #字典中的key值即为csv中列名
dataframe = pd.DataFrame({'电影名':name,'导演':director,'主演':star,'类型':types})
#dataframe = pd.DataFrame({'类型':types})
    #将DataFrame存储为csv,index表示是否显示行名,default=True
dataframe.to_csv("时光网数据.csv",index=False,sep=',')

 但是发现利用美丽汤效率极其低下,而且【if'导演:' in daoyan.text:】这种语句会识别所有包含“导演”这两个字的内容,导致内容错乱,所以放弃了使用美丽汤作为基本的库,经过大神的知道想着利用x-path作为基本的正则表达式来抓取效率更高,而且时光网数据量太小,不适合抓取,所以决定转战豆瓣,抓取豆瓣评分top500的电影。

 首先说一下正则表达式,他是python中最重要的部分之一,对于切割文字,去除多余字符等处理都及其有用,但是又相对复杂,学起来比较麻烦,但是好用啊,还得学习,感兴趣的可以去http://deerchao.net/tutorials/regex/regex.htm看看,

然后再来说说X-PATH,https://cuiqingcai.com/2621.html,在装该库的时候,就想装scapy一样,遇到了很多问题,但是大部分问题的原因都是:1、未添加环境变量,具体方法可以网上找找,一大堆;2、所下载的包有问题,具体方法可以参考此博客http://blog.csdn.net/c406495762/article/details/60156205;

 具体用法已经有很多大神说了,但是一开始确实是不好看懂,就举几个简单的例子好了,利用火狐浏览器+f12能够直接看到比较整齐的html代码,

例如图(1)是某网站框架

利用python抓取豆瓣top500的电影_第1张图片

图(1)某网站html框架


 图中

的x-path地址为/html/body/div/div[5]/div/div/div/div/div[2]/div[2]/ul/li[1]/div[2],但是这是绝对的地址,在抓取过程中只会抓取到改点,而无法抓取更多内容,所以应该找到每个框架下一些有规律的点的共同属性作为x-path的地址,所以上面这句话就可以使用x-path路径为://div[@class="mov_pic"],这样就能够找到所有包含在div标签下且属性为class="mov_pic"的地址。

再比如图(2)为肖申克的救赎的地址

利用python抓取豆瓣top500的电影_第2张图片

图(2) 肖申克的救赎的html地址

 包含电影名的x-path地址就是:/html/body/div/div[5]/div/div/div/div/div[2]/div[2]/ul/li[1]/div[3]/h2/a,而对于该网站框架下应该是所有包电影名的x-path地址都应该是://a[@class="c_fff"],但是当输出以上x-path时输出的是乱码或者一些字符,所以需要在其后面加上“text()”命令,便能获得里面的文字,比如在此就能获得电影名“肖申克的救赎 The Shawshank Redemption(1994)”了,所以说x-path的获取方法和效率都不知道比美丽汤高到哪里去了,所以在使用过程中还是比较推荐使用x-path。

# -*- coding: utf-8 -*-
"""
Created on Thu Jan 18 14:37:37 2018

@author: cxjoke
功能:抓取豆瓣top250的电影名字,导演。类型等,评分,评分人数等
"""


# -*- coding:UTF-8 -*-
import requests
from lxml import etree


if __name__ == '__main__':
    ranks=[]
    names=[]
    directors=[]
    types=[]
    juqing=[]
    stars=[]
    dd=[]
    gg=[]
    people=[]
    grades=[]
    quotes=[]
    numbers=['0','25','50','75','100','125','150','175','200','225']
    for number in numbers:
        url = 'https://movie.douban.com/top250?start={}&filter='.format(number)#实现翻页功能
       
        headers = {
            "User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
            }
        req = requests.get(url = url,headers = headers)
        req.encoding = 'utf-8'
        html = req.text
        html1=etree.HTML(html)
        rank=html1.xpath('//div[@class="item"]/div/em/text()')#x-path地址并获取文字
        for rank1 in rank:
            ranks.append(rank1)
        name=html1.xpath('//div[@class="info"]/div[1]/a/span[1]/text()')
        for name1 in name:
            names.append(name1)
        director=html1.xpath('//div[@class="bd"]/p[1]/text()')
        for director1 in director:
            directors.append(director1)
       
        people1=html1.xpath('//div[@class="star"]/span[4]/text()')
        for people2 in people1:
            people.append(people2)
        grade=html1.xpath('//div[@class="star"]/span[@class="rating_num"][@property="v:average"]/text()')
        for grade1 in grade:
            grades.append(grade1)
    


        quote=html1.xpath('//p[@class="quote"]/span/text()')
        for quote1 in quote:
            quotes.append(quote1)
        
 
    
        for i in directors:
            gg.append(i.strip())
        for k in gg:
            dd.append("".join(k.split()))
   
        for q in range(25):
            juqing.append(dd[2*q-1])
        for q in range(25):
            stars.append(dd[2*q])
      
import pandas as pd
    #字典中的key值即为csv中列名
columns1= ['豆瓣排名','电影名','剧情','导演/主演','评分','评价人数','queto']#csv会按首字母进行排序,所以加表格自己排序
dataframe = pd.DataFrame({'豆瓣排名':ranks,'电影名':names,'剧情':juqing,'导演/主演':stars,'评分':grades,'评价人数':people,'queto':quotes})
#dataframe = pd.DataFrame({'类型':types})
    #将DataFrame存储为csv,index表示是否显示行名,default=True
dataframe.to_csv("豆瓣电影top250.csv",encoding="utf_8_sig",index=False,columns=columns1)

总结:

  大概花了三天时间,结合大神的讲解写了两个性能不算太好的爬虫,其中有个bug就是获取的数据必须长

度一样,要不然就无法写入csv,所以在获取数据之后还要进行数据的一些简单的处理,方法比较简单就不

细说了,总体来说python是一个很智能并且有意思的语言,前段时间把周志华的《机器学习》和李航的《统计

学习方法》啃了一遍,并且现在想着试着实现一下里面的算法,后期内容更精彩,敬请期待哦!



你可能感兴趣的:(利用python抓取豆瓣top500的电影)