电影排行榜爬取

本文介绍如何使用Python的urllib和BeautifulSoup库抓取豆瓣电影Top250的影片信息,包括链接、图片、名称、评分、评价数等,并通过Excel和数据库进行数据保存。同时,展示了正则表达式在解析网页内容中的应用。
摘要由CSDN通过智能技术生成

大概步骤:
1.爬取网页(这里用的urllib)
2.逐一解析数据
3.保存数据(excel ,数据库存储)

1.爬取网页

网页的访问一般两种方式:

# 1.get请求
url = "https://movie.douban.com/top250?start=0&filter="
respense = urllib.request.urlopen(url)  #请求访问网页
print(respense.read().decode("utf-8"))  #将返回的对象进行解码读取

url = "https://www.baidu.com/"
# 请求头
headers ={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67",

"Host": "www.baidu.com", "Referer": "https://cn.bing.com/"

}

dict = {"name": "tom"}

data = bytes(urllib.parse.urlencode(dict), encoding = "utf-8") # 转为字节类型


# 由于urlopen无法传参数,声明一个Request对象
request = urllib.request.Request(url, data = data, headers = headers, method = 'POST')
respense = urllib.request.urlopen(request)
print(respense.read().decode('utf-8'))

一般采用方式二,用request封装一个request对象(包含请求头和更多的信息),再用urlopen()访问。

访问一个指定的网址

# 访问一个指定的网址
def askURL(url):
    # 模拟浏览器头部信息,向豆瓣服务器发送消息
    head = {  # 用户代理 表示告诉豆瓣服务器,我们是什么类型的 机器,浏览器
        "User-Agent": "Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 92.0 .4515.131Safari / 537.36Edg / 92.0.902.67"
    }

    request = urllib.request.Request(url, headers = head)    # 返回一个对象
    html = ""
    try:
        respense = urllib.request.urlopen(request)
        html = respense.read().decode('utf-8')
        print(html)
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)

    return html

2.解析数据

解析数据有三种:re,bs4,xpath
一般以BeautifulSoup,re配合正则表达式对爬取到的数据进行解析

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为四大对象种类:
	1. Tag
	2. NavigableString
	3. BeautifulSoup
	4. Comment
import re
from bs4 import BeautifulSoup

file = open("./baidu.html", 'rb')               # 打开当前目录下的文件 ./
html = file.read()                              # 读取文件并返回给html对象
bs = BeautifulSoup(html, "html.parser")         # html解析 并返回bs对象

list_a =bs.find_all("a")                         # 打印出所有标签 a的整个信息
# 1.tag(就是标签)  有两个属性 :name ,attrs
print(bs.a.attrs)                               # 获取标签a的所有属性 以键值对返回
# 利用get()     传入属性的名称
print(bs.a['class'])    # 等价于 bs.a.get("class")


# 2.NavigableString (获取标签内部的文字) 用.string
print(bs.a.string)


# 3.BeautifulSoup 表示是一个文档的内容, 可以当中特殊的tag ,可以获取它的属性,类型,名称
print(bs.name)
print(bs.attrs)
print(type(bs))                      # <class 'bs4.BeautifulSoup'>

# 4.Comment 其对象是一个特殊类型的 NavigableString 对象,其输出的内容不包括注释符号。
print(bs.a.string)
print(type(bs.a.string))              # <class 'bs4.element.Comment'>


# 搜索 find_all(name, attrs, recursive, text, **kwargs) 过滤器

# (1)name  字符串过滤:会查找与字符串完全匹配的内容
# limit限制标签返回的数量    也可以使用find() 该函数返回一个
a_list = bs.find_all('a', limit = 3)                 # 查找 a标签
for i in a_list:
    print(i)

正则表达式:一种文本模式,描述在搜索文本时要匹配的一个或多个字符串

常用操作符:

. 匹配除换⾏符以外的任意字符
\w 匹配字⺟或数字或下划线
\s 匹配任意的空⽩符
\d 匹配数字
\n 匹配⼀个换⾏符
\t 匹配⼀个制表符
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W 匹配⾮字⺟或数字或下划线
\D 匹配⾮数字
\S 匹配⾮空⽩符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示⼀个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符



* 重复零次或更多次
+ 重复⼀次或更多次
? 重复零次或⼀次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

正则表达式中的 .,.?,.+? 的理解
(1).*
. 表示 匹配除换行符 \n 之外的任何单字符,*表示零次或多次。所以.*在一起就表示任意字符出现零次或多次。没有?表示贪婪模式。比如a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
又比如模式src=.*, 它将会匹配最长的以 src=开始,以结束的最长的字符串。用它来搜索 <img src=test.jpg` width=`60px` height=`80px`/> 时,将会返回 src=test.jpgwidth=60pxheight=80px`

(2).?
?跟在
或者+后边用时,表示懒惰模式。也称非贪婪模式。就是匹配尽可能少的字符。就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
a.?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
又比如模式 src=.*?,它将会匹配 src=开始,以 结束的尽可能短的字符串。且开始和结束中间可以没有字符,因为
表示零到多个。用它来搜索 <img src=test.jpg` width=`60px` height=`80px`/> 时,将会返回 src=

(3).+?
?跟在*或者+后边用时,表示懒惰模式。也称非贪婪模式。就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
a.+?b匹配最短的,以a开始,以b结束的字符串,但a和b中间至少要有一个字符。如果把它应用于ababccaab的话,它会匹配abab(第一到第四个字符)和aab(第七到第九个字符)。注意此时匹配结果不是ab,ab和aab。因为a和b中间至少要有一个字符。
又比如模式 src=.+?,它将会匹配 src=开始,以 结束的尽可能短的字符串。且开始和结束中间必须有字符,因为+表示1到多个。用它来搜索 <img src=test.jpg` width=`60px` height=`80px`/> 时,将会返回 src=test.jpg。注意与.*?时的区别,此时不会匹配src=``,因为src= 和 ` 之间至少有一个字符。

如果正则表达式使用了 (?P…) 语法, group 参数就也可能是命名组合的名字。

 # 获取目的字符串
    a = re.match(r'(?P<first>\w+) (?P<second>\wt)', "Tom  Jan")
    a.group("first")     # Tom
    a.group(1)
    a.group("second")    # Jan
    a.group(2)



re与正则表达式配合,搜索目标字符串

1.compile(pattern)
2.search(pattern,string)
3.sub(pat,repl,string)

```python
import re

if __name__ == "__main__":
    # 1.compile(pattern):创建模式对象
    pat = re.compile("AAC")           # 创建匹配对象 也就是正则表达式
    res = pat.search("adAAdsdAACda")  # 将正则表达式与search里面的匹配字符串进行比较 一般返回第一个位置
    print(res)


    # 2.search(pattern,string):在字符串中寻找模式
    # 不用创建匹配对象,直接寻找
    m = re.search("AAC", "adAAdsdAACda")  #第一个参数是正则表达式 第二个是匹配字符串
    print(m)

    # 3.sub(pat,repl,string) :用repl替换 pat匹配项 (留的是中间的,因为中间在中心)
    l = re.sub('a', 'S', "hhgaaahAnuaa")   #将第三个字符串中的a用S代替
    print(l)

影片信息的正则表达式

# 影片详情链接的正则表达式
findLink = re.compile(r'<a href="(.*?)">')                                             # .*? 懒惰模式正则 匹配到第一个就不匹配了
# 影片图片链接
findImage = re.compile(r'<img.*src="(.*?)"', re.S)                                  # re.S 将包含换行的字符看成一个整体
# 影片的标题
findTitle = re.compile(r'<span class="title">(.*)</span>')
# 影片评分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')  # 评分含小数点当成字符串 不用\d
# 影片评价人数
findJudge = re.compile(r'<span>(\d*)人评价</span>')                                     # 人数全是整数 用\d
# 影片的概述
findInq = re.compile(r'<span class="inq">(.*)</span>')
# 影片相关内容
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)



3.保存数据
1.excel保存
xlwt库

```python
import xlwt
workbook = xlwt.Workbook(encoding = 'utf-8')          # 创建workbook对象,也就是一个文件
worksheet = workbook.add_sheet('sheet1')              # 创建工作表
# worksheet.write(0, 0, '1321')                     # 往表中传参数,前两个参数是行,列,最后一个为内容
# workbook.save('Student.xls')                          # 保存表为Student.xls
# 打印在表中九九乘法表
for i in range(1, 10):
    for j in range(1, 10):
        if i >= j:
            worksheet.write(i-1, j-1, "{}*{}={}".format(j, i, i*j))
workbook.save('Student.xls')                          # 保存表为Student.xls

保存:

def saveData(datalist, savepath):
    print("save.....")
    book = xlwt.Workbook(encoding='utf-8', style_compression=0)            # 创建workbook对象,也就是一个文件
    sheet = book.add_sheet("豆瓣电影250Top", 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)

2.数据库存储

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super.Bear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值