python爬虫入门实例
这周的CTF的web题没有写很多,因为要复习应考的原因,就零零碎碎的做了2、3题,等题目量多了在出一篇博客做记录叭,但是博客还是每周尽量出一篇叭,鞭策一下自己的课外学习。
那么这篇博客主要是记录一下,如何用python做一个简易的爬虫,这里只是对一些网页中的静态数据的爬取,以后爬爬小论文,实验数据还是比较实用,所以在这里做一个小记录。相当一个入门的小实例,同时我发现,网上的的爬虫代码上的注释写的比较少,不适合初学者,我的代码还是写了一些比较详细的注释的,看起来比较简单叭。
那么我们开始吧。在网站上爬取静态数据,首先要了解一下,html的源代码,你所要的数据是什么,找到对应的标签,之后就是分析标签的嵌套。然后在就是编写Python的代码。
这个爬虫实现的是对豆瓣网站前250部电影的信息爬取,之后保存到excel文件里面
运行之前还是要安装一些第三方库的(如果是anaconda应该就不用了)
pip install bs4
pip install requests
pip install pandas
等。。应该还有一些emmmm看报错信息,运行不了会提示你安装什么库的。。。
首先我们先分析一下这个网页:https://movie.douban.com/top250
自己最好登录一下,查看一下源代码,分析一下,看下面的代码会理解的快一点。
综上分析,所有的数据都在标签ol里面
ol里面有好多的li标签而li标签里面的内容就是我们所要爬取的内容
里面有我们所要所爬取的信息,有以下几点
‘’’
影片的序号, 影片的影片链接,影片的图片链接,影片的影片名,影片的介绍,影片的豆瓣评分,影片的评分人数,影片的评论
‘’’
这里简单介绍一下html的基础语法
html是通过不同的元素来实现对应的功能的比如<p>内容</p>
,这个是p标签,通过p标签放入文本文件,类似python print()
还有本实例中所涉及的<ol></ol><li></li><div></div><span></span>
标签
<ol></ol><li></li>
是一对,是形成一个列表结构的文本
例如:
<ol>标题
<li>python</li>
<li>C语言</li>
<li>html</li>
</ol>
最后输出的格式:
标题
python
C语言
html
类似的列表结构的文本,本例所对应得到的html结构便是如此
<div></div>
所起到的作用是一个分隔页面的效果,其实只是一个万能标签,没有多大意义,但是作用很大,这里不细说了
<span></span>
类似div其实也只是一个万能标签,没有多大意义,但是作用很大起到分隔,存放少许信息,这里也不细说了
还有一点就是属性选择器,在html源码中见到很多<div class="item"></div>
或者<div id="item"></div>
class 和id就是属性选择器,主要是通过这个让标签绑定一个名字(item),更好的对标签实现css页面渲染,这个也不细说了
因为最后要保存为excel文件,所以我们在python里面要构建的是一个字典,结构应该是这样的
{
“影片的序号”:[]
“影片的影片链接”:[]
“影片的图片链接”:[]
“影片的影片名”:[]
“影片的介绍”:[]
“影片的豆瓣评分”:[]
“影片的评分人数”:[]
“影片的评论”:[]
}
用python的pandas所提供的dataframe方法,将其构建成相应的l数据格式,这个格式是对于很多文件通用的,比如可以保存为CSV格式的文件JSON格式的文件,包括excel文件。
保存为excel文件,就用dataframe所提供的的to_excel()方法,类似的有to_json()方法保存为json文件 to_csv()csv文件。
那么我们废话不多说,上代码,这里代码有详细的注释,我就不再赘述了,看代码就好。
import requests#用于获取网页的html源码
from bs4 import BeautifulSoup#用于对网页html源码的解析,用这个就避免使用正则表达式所带的烦恼
import pandas as pd#用与数据保存的文件(excel,json等)
#本例的类
class CatchBug:
#对象的初始化方法
def __init__(self):
#初始化开始,建立一个字典,用于存放数据
self.movie_dic={}
#初始化开始,建立一个列表,用于存放数据的头部信息
self.dic_key=["序号","影片链接","图片链接","影片名","影片介绍","豆瓣评分","评分人数","影片评论"]
#初始化开始,对字典中的每个的键值造一个列表,实现对应的数据存放
for key in self.dic_key:
self.movie_dic[key]=list()
#抓取数据方法
def ActionCatch(self):
#从这个top250的榜单上我们可以看出,每一页的数据是有25个,所以要遍历10次
for i in range(0,251,25):
#构造url,每页数据所对应的路由(ip)
url="https://movie.douban.com/top250?start="+str(i)+"&filter="
#print(url)debug
#建立一个伪造的头部信息,对于每一个网站其实都有对应的检测头部信息,如果是错误的头部信息那就获取不到正确的网页文件(html文件)
head={'User-Agent':'Mozilla/5.0'}
#通过使用request模块方法,传入正确的url,和伪造的头部信息,得到html源码文件
html = requests.get(url,headers=head)
#print(html) debug
demo = html.text #demo 表示被解析的html格式的内容。以便下面直接可以查找对应的标签信息得到相应的信息
# 通过使用BeautifulSoup方法,传入html文件信息,进行对源代码的解析,html.parser表示解析用的解析器
soup = BeautifulSoup(demo, "html.parser")
#print(soup) # 输出响应的html对象,调试代码
#print(soup.prettify()) # 使用prettify()格式化显示输出,调试代码
#BeautifulSoup对象的对应的方法,find(msg,attrs),可以找到一个msg所对应的标签,后面是html中所对应的属性选择器:
#找一个ol标签返回回来<ol></ol>里面的所有内容
tag_ol=soup.find("ol")
#找所有的(all)的li标签.ol里面的(有25个).返回一个列表
tag_li=tag_ol.find_all("li")
#遍历列表
for tag in tag_li:
#找名为item的div标签<div class="item">
div_item=tag.find("div",attrs={"class":"item"})
#在item里找名为pic的div标签<div class='pic'>
div_pic=div_item.find("div",attrs={"class":"pic"})
#在pic里找em标签,得到里面的值用.string方法,得到电影排序
movies_num=div_pic.find("em").string
#在pic里找a标签(超链接),得到里面的链接值用(函数返回的是字典)(字典键值href),得到电影链接
movies_url=div_pic.find("a")["href"]
#在pic里找img标签(可以放图片),得到里面的图片链接值用(函数返回的是字典)(字典键值src),得到电影链接
movies_image_url=div_pic.find("img")["src"]
#在item里找名为pic的div标签<div class='info'>
div_info=div_item.find("div",attrs={"class":"info"})
#在info里找名为hd的div标签<div class='hd'>
div_hd=div_info.find("div",attrs={"class":"hd"})
#在hd里面找名为title的span标签,获得对应值,电影的片名
movies_title=div_hd.find("span",attrs={"class":"title"}).string
#在info里找名为bd的div标签<div class='bd'>
div_bd=div_info.find("div",attrs={"class":"bd"})
#在bd里找名为""的p标签<div class='pic'>这里用getText()获取值可以隔绝<br/>(换行)的干扰,得到影片的介绍
movies_content=div_bd.find("p",attrs={"class":""}).getText()
#在bd里找名为star的div标签<div class='star'>
div_star=div_bd.find("div",attrs={"class":"star"})
#在star里找名为rating_num的span标签<span class='rating_num'>,获取值,得到电影评分
movies_rating=div_star.find("span",attrs={"class","rating_num"}).string
#在star里找span标签<span >,第四个标签记录了电影评分人数信息
movies_ping=div_star.find_all("span")[3].string
#在bd里找名为inq的span标签<span class='inq'>,第四个标签记录了电影评论信息
#这里可能会找不到评论内容,会报错,所以设置判断
if div_bd.find('span',attrs={'class':"inq"}):
movies_quote=div_bd.find("span",attrs={"class":"inq"}).string
else:
movies_quote=""
#将获取到的信息构建成列表
list_info=[movies_num,movies_url,movies_image_url,movies_title,movies_content,movies_rating,movies_ping,movies_quote]
flag=0#设置列表索引
#遍历键值列表,将爬到的数据写入字典中
for key in self.dic_key:
#这里分别对数据信息进行,优化剔除\n \xa0 空格等字符可以不使用
#list_info[flag]=str(list_info[flag]).replace("\n","")
# list_info[flag]=str(list_info[flag]).replace("\xa0","")
# list_info[flag]=str(list_info[flag]).replace(" ","")
#插入字典键值所对应的链表
self.movie_dic[key].append(list_info[flag])
flag+=1
#返回字典
return self.movie_dic
#数据保存方法
def save_excel(self,filename):
#用pands模块方法,建立数据框架,放入字典
datafram=pd.DataFrame(self.movie_dic)
#将数据框架写入,excel文件
datafram.to_excel(filename)
#主函数
def main():
#构造爬虫对象
object=CatchBug()
#爬取数据
object.ActionCatch()
#存储数据
object.save_excel("movies_info.xlsx")#自己可以尝试修改一下文件运行一下,excel文件哈
if __name__=='__main__':
main()
最后的excel文件:
我也主要是偷一下懒,准备备考。哈哈哈。