前几天突然心血来潮想写一个爬虫,所以一开始写了一个抓取时光网数据的爬虫,主要用了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)是某网站框架
图(1)某网站html框架
图中 再比如图(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。 总结: 大概花了三天时间,结合大神的讲解写了两个性能不算太好的爬虫,其中有个bug就是获取的数据必须长 度一样,要不然就无法写入csv,所以在获取数据之后还要进行数据的一些简单的处理,方法比较简单就不 细说了,总体来说python是一个很智能并且有意思的语言,前段时间把周志华的《机器学习》和李航的《统计 学习方法》啃了一遍,并且现在想着试着实现一下里面的算法,后期内容更精彩,敬请期待哦!# -*- 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)