python爬虫实战之爬取豆瓣Top250电影信息

在学习python基础以及一些爬虫基础概念之后,为了加深自己对知识的理解,于是跟着视频以及结合自己的心得,记录自己这段时间学习爬虫的实战项目心得。

【准备工作】

1.豆瓣电影Top250网站地址:https://movie.douban.com/top250

2.会使用浏览器开发者模式查找 User-Agent(这个东西的作用主要是防止我们爬取网页别系统检测到,后文我们会讲解)

3.会使用python中的相关库:re、urllib、xlwt、BeautifulSoup、request

re(Python的标准库,主要用于字符串匹配):https://www.cnblogs.com/beiyin/p/9129604.html

urllib(python内置的http请求库):https://www.cnblogs.com/qikeyishu/p/10748497.html

xlwt(操作excel主要用到xlrd和xlwt这两个库):https://www.cnblogs.com/liuguojun/p/11329594.html

BeautifulSoup(最主要的功能是从网页抓取数据,并解析):https://www.cnblogs.com/scios/p/8652760.html

 

【开始工作】

1.爬取网页首先我们需要获取网页链接,我们定义一个函数名字叫做:askURL(url)

# 获取网页链接
def askURL(url):
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
    }
    req = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(req)
        html = response.read().decode('utf-8')  # read()获取响应体的内容,内容是bytes字节流,需要转换成字符串
        #print(html)

    except urllib.error.URLError as e:  # 处理异常,如果被检测到了返回418
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)

    return html

可以看到我们写的函数里面有一段这样的代码,这句话主要是用于防止被监测到

head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
    }
  req = urllib.request.Request(url, headers=head)

那么我们如何获取到head里面这些东西呢,操作如下:

打开豆瓣电影Top250 https://movie.douban.com/top250,快捷键(Fn+F12)我的是笔记本,台式的话就是F12,如下所示

python爬虫实战之爬取豆瓣Top250电影信息_第1张图片

我们刷新下网页,出现如下所示

python爬虫实战之爬取豆瓣Top250电影信息_第2张图片

这里我们可以测试下我们获取的网页内容

import urllib
import re
import xlwt
from bs4 import BeautifulSoup
from urllib import request


def main():
    baseUrl = 'https://movie.douban.com/top250?start='
    askURL(baseUrl)



# 获取网页链接
def askURL(url):
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
    }
    req = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(req)
        html = response.read().decode('utf-8')  # read()获取响应体的内容,内容是bytes字节流,需要转换成字符串
        print(html)

    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)

    return html




if __name__ == '__main__':
    main()

测试结果如下(截取一小部分):

python爬虫实战之爬取豆瓣Top250电影信息_第3张图片

2.爬取了网页接下来我们需要的就是获取网页内容,我们写一个叫做 getData(baseUrl)的函数

通过分析我们可以看到豆瓣电影Top250 一页有25部电影,而且每一页对应的url也不同,如下所示

这是首页和第二页的地址,到了第二页url的格式就不同了,start=25代表的是上一页最后一部电影的编号

https://movie.douban.com/top250
https://movie.douban.com/top250?start=25&filter=

所以我们可以想一个办法将上面的url改成如下所示

https://movie.douban.com/top250?start=0
https://movie.douban.com/top250?start=25

因为有250部电影,所以每一页有25部,共10页,可以通过下面这个方法获取到每一页的完整url

# baseUrl是我们传入的地址 ,str(i*25)相当于start后面的数字
for i in range(0, 10):
        url = baseUrl + str(i*25)

这样我们来简单测试下通过传入完成的url来解析后获得的数据是什么

import urllib
import re
import xlwt
from bs4 import BeautifulSoup
from urllib import request


def main():
    baseUrl = 'https://movie.douban.com/top250?start='
    getData(baseUrl)
    #askURL(baseUrl)




# 爬取网页
def getData(baseUrl):
    datalist = []
    for i in range(0, 10):
        url = baseUrl + str(i*25)
        html = askURL(url)  # 保存获取到的网页
        print(html)

       

# 获取网页链接
def askURL(url):
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
    }
    req = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(req)
        html = response.read().decode('utf-8')  # read()获取响应体的内容,内容是bytes字节流,需要转换成字符串
        #print(html)

    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)

    return html





if __name__ == '__main__':
    main()
    print("爬取完毕。")

测试结果如下:

python爬虫实战之爬取豆瓣Top250电影信息_第4张图片

上面测试我们可以获取这250部电影的相关信息,但是这里面的一些标签却不是我们想要的内容,所以我们需要解析,然后过滤掉这些对我们没有用的数据。

import urllib
import re
import xlwt
from bs4 import BeautifulSoup
from urllib import request


def main():
    baseUrl = 'https://movie.douban.com/top250?start='
    getData(baseUrl)



# 爬取网页
def getData(baseUrl):
    datalist = []
    for i in range(0, 10):
        url = baseUrl + str(i*25)
        html = askURL(url)  # 保存获取到的网页
        # 逐一解析数据
        soup = BeautifulSoup(html, 'html.parser')  # 也可以使用lxml代替html.parser作为解析器
        print(soup.find_all('div', class_="item"))
       


# 获取网页链接
def askURL(url):
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
    }
    req = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(req)
        html = response.read().decode('utf-8')  # read()获取响应体的内容,内容是bytes字节流,需要转换成字符串
        #print(html)

    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)

    return html



if __name__ == '__main__':
    main()
    print("爬取完毕。")

通过解析器我们可以看到每一部电影在网页中的具体位置,测试结果如下(截取一部电影):

1 肖申克的救赎

导演: 弗兰克·德拉邦特 Frank Darabont   主演: 蒂姆·罗宾斯 Tim Robbins /...
1994 / 美国 / 犯罪 剧情

9.7 2143966人评价

希望让人自由。

这段代码的意思就是通过查找标签为div里面且属性class=“item”里面的所有内容,就是上面我们看到的这部分

soup.find_all('div', class_="item")

好了,既然获取到了主体部分,接下来我们就要根据我们的需求获取影片链接、影片图片、影片名字、影片评分、影片评价人数、影片概况以及影片内容

import urllib
import re
import xlwt
from bs4 import BeautifulSoup
from urllib import request


def main():
    baseUrl = 'https://movie.douban.com/top250?start='
    # 爬取网页
    #datalist = getData(baseUrl)
    getData(baseUrl)

    askURL(baseUrl)


# 创建影片超链接正则表达式
findLink = re.compile(r'')
# 创建图片正则表达式
findImgSrc = re.compile(r'(.*)')
# 创建评分正则表达式
findRating = re.compile(r'(.*)')
# 创建评价人数正则表达式
findJudge = re.compile(r'(\d*)人评价')
# 创建概况正则表达式
findInq = re.compile(r'(.*)')
# 创建影片相关内容正则表达式
findBd = re.compile(r'

(.*?)

', re.S) # 爬取网页 def getData(baseUrl): datalist = [] for i in range(0, 10): url = baseUrl + str(i*25) html = askURL(url) # 保存获取到的网页 # 逐一解析数据 soup = BeautifulSoup(html, 'html.parser') # 也可以使用lxml代替html.parser作为解析器 #print(soup.find_all('div', class_="item")) # 通过条件筛选我们需要的列表 for item in soup.find_all('div', class_="item"): data = [] # 保存一部电影的所有信息 item = str(item) # 将列表转换为字符串 # 获取影片超链接 link = re.findall(findLink, item)[0] # re库通过正则表达式来查找指定的字符串 data.append(link) # 添加超链接 # 获取图片链接 imgSrc = re.findall(findImgSrc, item)[0] data.append(imgSrc) # 添加图片链接 # 获取文章标题 titles = re.findall(findTitle, item) # 片名可能只有中文名,没有外国名 if len(titles) == 2: # 如果有中文和外国名需要分别添加 ctitle = titles[0] data.append(ctitle) # 添加中文名 otitle = titles[1].replace("/", " ") # 去掉标题中的/字符 data.append(otitle.split()) # 添加英文名,并将空格去掉 else: data.append(titles[0]) data.append(" ") # 留空 # 获取影片评分 rating = re.findall(findRating, item)[0] data.append(rating) # 添加影片评分 # 获取评价人数 judge = re.findall(findJudge, item)[0] data.append(judge) # 添加评论人数 # 获取概况 inq = re.findall(findInq, item) data.append(inq) # 添加概况 # 获取影片内容 bd = re.findall(findBd, item)[0] bd = re.sub('(\\s+)', " ", bd) # 使用空格替换掉' bd = re.sub('/', " ", bd) # 使用空格替换掉/ data.append(bd.split()) # 去掉前后的空格(\xa0代表空白符  使用strip()无法去掉) print(data) datalist.append(data) # 将一页的电影信息添加进去 return datalist # 获取网页链接 def askURL(url): head = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" } req = urllib.request.Request(url, headers=head) html = "" try: response = urllib.request.urlopen(req) html = response.read().decode('utf-8') # read()获取响应体的内容,内容是bytes字节流,需要转换成字符串 #print(html) except urllib.error.URLError as e: if hasattr(e,"code"): print(e.code) if hasattr(e,"reason"): print(e.reason) return html if __name__ == '__main__': main() print("爬取完毕。")

运行结果如下:

python爬虫实战之爬取豆瓣Top250电影信息_第5张图片

3.爬取到了数据接下来我们需要保存数据(这里我们采取保存数据到excel中)

# 保存数据
def saveData(datalist,savepath):
    # 创建工作簿
    book = xlwt.Workbook(encoding="utf-8")
    # 创建工作表
    sheet = book.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True)  # cell_overwrite_ok=True, 可以覆盖原单元格中数据
    col = ("电影详情链接", "图片链接", "影片中文名", "影片外国名", "影片评分", "影片评价人数", "影片概况", "影片内容")  # 设置表格的列名
    # 写入数据
    for i in range(0, 8):   
        sheet.write(0, i, col[i])  # 将每一列的列名写入到第一行
    for i in range(0, 250):
        print("第%d条" % (i+1))
        data = datalist[i]
        for j in range(0, 8):  # 将每一行的数据写入到对应的列
            sheet.write(i+1, j, data[j])
    # 保存数据
    book.save(savepath)

完整代码

import urllib
import re
import xlwt
from bs4 import BeautifulSoup
from urllib import request


def main():
    baseUrl = 'https://movie.douban.com/top250?start='
    # 爬取网页
    datalist = getData(baseUrl)
    savepath = '豆瓣电影Top250.xls'
    # 保存数据
    saveData(datalist, savepath)

    askURL(baseUrl)


# 创建影片超链接正则表达式
findLink = re.compile(r'')
# 创建图片正则表达式
findImgSrc = re.compile(r'(.*)')
# 创建评分正则表达式
findRating = re.compile(r'(.*)')
# 创建评价人数正则表达式
findJudge = re.compile(r'(\d*)人评价')
# 创建概况正则表达式
findInq = re.compile(r'(.*)')
# 创建影片相关内容正则表达式
findBd = re.compile(r'

(.*?)

', re.S) # 爬取网页 def getData(baseUrl): datalist = [] for i in range(0, 10): url = baseUrl + str(i*25) html = askURL(url) # 保存获取到的网页 # 逐一解析数据 soup = BeautifulSoup(html, 'html.parser') # 也可以使用lxml代替html.parser作为解析器 #print(soup.find_all('div', class_="item")) # 通过条件筛选我们需要的列表 for item in soup.find_all('div', class_="item"): data = [] # 保存一部电影的所有信息 item = str(item) # 将列表转换为字符串 # 获取影片超链接 link = re.findall(findLink, item)[0] # re库通过正则表达式来查找指定的字符串 data.append(link) # 添加超链接 # 获取图片链接 imgSrc = re.findall(findImgSrc, item)[0] data.append(imgSrc) # 添加图片链接 # 获取文章标题 titles = re.findall(findTitle, item) # 片名可能只有中文名,没有外国名 if len(titles) == 2: # 如果有中文和外国名需要分别添加 ctitle = titles[0] data.append(ctitle) # 添加中文名 otitle = titles[1].replace("/", " ") # 去掉标题中的/字符 data.append(otitle.split()) # 添加英文名,并将空格去掉 else: data.append(titles[0]) data.append(" ") # 留空 # 获取影片评分 rating = re.findall(findRating, item)[0] data.append(rating) # 添加影片评分 # 获取评价人数 judge = re.findall(findJudge, item)[0] data.append(judge) # 添加评论人数 # 获取概况 inq = re.findall(findInq, item) data.append(inq) # 添加概况 # 获取影片内容 bd = re.findall(findBd, item)[0] bd = re.sub('(\\s+)', " ", bd) # 使用空格替换掉' bd = re.sub('/', " ", bd) # 使用空格替换掉/ data.append(bd.split()) # 去掉前后的空格(\xa0代表空白符  使用strip()无法去掉) datalist.append(data) # 将一页的电影信息添加进去 return datalist # 获取网页链接 def askURL(url): head = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" } req = urllib.request.Request(url, headers=head) html = "" try: response = urllib.request.urlopen(req) html = response.read().decode('utf-8') # read()获取响应体的内容,内容是bytes字节流,需要转换成字符串 #print(html) except urllib.error.URLError as e: if hasattr(e,"code"): print(e.code) if hasattr(e,"reason"): print(e.reason) return html # 保存数据 def saveData(datalist,savepath): # 创建workBook对象 book = xlwt.Workbook(encoding="utf-8") # 创建工作表 sheet = book.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True) # cell_overwrite_ok=True, 可以覆盖原单元格中数据 col = ("电影详情链接", "图片链接", "影片中文名", "影片外国名", "影片评分", "影片评价人数", "影片概况", "影片内容") # 写入数据 for i in range(0, 8): sheet.write(0, i, col[i]) for i in range(0, 250): print("第%d条" % (i+1)) data = datalist[i] for j in range(0, 8): sheet.write(i+1, j, data[j]) # 保存数据 book.save(savepath) if __name__ == '__main__': main() print("爬取完毕。")

运行结果如下:

在编译器左侧生成了一个豆瓣电影Top250.xls的表格

点击表格,我们可以看到如下结果:

python爬虫实战之爬取豆瓣Top250电影信息_第6张图片

python爬虫实战之爬取豆瓣Top250电影信息_第7张图片

 

参考资料:五天学会爬虫(这里主要看15-25节视频就可以,这个视频讲解的非常好)

 

你可能感兴趣的:(Python爬虫实战)