前提:需要有python和pip环境
写在前言处:需要了解前端的HTML标记和CSS样式,了解python的基本用法
爬虫 首先了解一下爬虫是什么,还有什么注意事项。
爬虫(Web crawler)是一种自动化程序或脚本,用于浏览互联网并自动提取网页内容的工具。它也被称为网络爬虫、网络蜘蛛或网络机器人。
爬虫通过发送HTTP请求访问指定的网页,并从返回的内容中提取有用的信息,例如文本、图片、链接等。它们通常用于数据采集、搜索引擎索引、数据分析、监测网站变化等任务。
爬虫的工作原理通常是:
指定一个初始URL作为爬取的起点。 发送HTTP请求获取网页内容。 解析HTML内容,提取感兴趣的数据,例如链接、文本等。 如果有新的链接,将其添加到待爬取的URL队列中。 重复执行步骤2-4,直到满足终止条件(例如爬取的页面数量达到设定值或达到指定深度)。 爬虫可以针对特定的网站进行定向爬取,也可以通过搜索引擎的爬虫来广泛地爬取整个互联网。
注意事项 在爬取过程中,爬虫需要遵守网站的爬取规则 和道德准则 ,以避免对网站造成过大的负担或侵犯隐私等问题。
准备工作 安装requests和bs4库 分别在powershell里面执行
1 2 pip install requests pip install bs4
在Python中,BeautifulSoup(通常简称为bs4)是一个用于解析HTML和XML文档的库。
BeautifulSoup的主要作用如下:
解析HTML和XML文档:BeautifulSoup可以将HTML或XML文档解析为Python对象,使得我们可以方便地提取其中的数据。 树形结构遍历:BeautifulSoup将解析的文档构建为树形结构,通过遍历这个结构,我们可以轻松地定位和访问文档中的各个元素。 数据提取:通过BeautifulSoup提供的一系列方法,我们可以根据标签、类名、属性等条件来提取文档中的数据。例如,我们可以提取所有的链接、图片、段落等。 数据清洗:BeautifulSoup还可以清洗和格式化提取到的数据。它提供了一些方法来去除HTML标签、删除多余的空白字符等,使得提取到的数据更加干净和易于处理。 弥补HTML解析器的不足:BeautifulSoup可以与不同的HTML解析器(如Python内置的html.parser、lxml等)配合使用,以弥补解析器在处理不规范或复杂HTML时的不足之处。 一个简单的小Demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import requestsfrom bs4 import BeautifulSoupdef web_crawler (url ): response = requests.get(url) if response.status_code == 200 : soup = BeautifulSoup(response.text, "html.parser" ) links = soup.find_all("a" ) for link in links: title = link.text href = link.get("href" ) print (f"Title: {title} \nURL: {href} \n" ) else : print ("Failed to fetch the webpage" ) url = "https://sanxiaoxing.github.io/" web_crawler(url)
在web_crawler
函数内部,我们首先发起GET请求,并检查响应状态码。如果响应状态码为200,表示请求成功,我们使用BeautifulSoup
解析HTML内容。
接下来,我们使用find_all
方法获取网页中所有的<a>
标签,并遍历每个链接。我们使用text
属性获取链接的文本内容,使用get
方法获取链接的URL,并打印标题和URL。
最后,我们在主程序中指定要爬取的网页URL,并调用web_crawler
函数来执行爬取操作。
除此之外,有的网站会限制python爬虫进行数据的爬取,这时我们可以使用
1 2 header = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0' }
进行web的伪装。
提示:user-Agent
可以使用web浏览器F12
的开发者选项中的网络
,进行刷新,随便点击一个即可看到user-Agent
的一个内容
把鼠标移动到我上面试试 继续爬取豆瓣电影 了解以上的内容,就可以简单爬取一下豆瓣的电影了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import requestsfrom bs4 import BeautifulSoupurl = 'https://movie.douban.com/top250' headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36' } response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser' ) movies = soup.find_all('div' , class_='info' ) for movie in movies: title = movie.find('span' , class_='title' ).text rating = movie.find('span' , class_='rating_num' ).text print (f'电影名字: {title} \t评分: {rating} ' )
根据上面的代码,不难发现只有第一页的内容,而我们需要前250的内容
豆瓣排名前250名的总排名 那么,我们需要使用一个循环处理每一个页面range(0,250,25)
。标识0到250,每次增加25,以便处理页面。
https://movie.douban.com/top250?start=0&filter=
在这个连接里面不难看出start
是0,翻到下一页就是25,可以得出所需要增加的为25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import requestsfrom bs4 import BeautifulSoupheaders = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36' } for page in range (0 , 250 , 25 ): url = f'https://movie.douban.com/top250?start={page} ' response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser' ) movies = soup.find_all('div' , class_='info' ) for movie in movies: title = movie.find('span' , class_='title' ).text rating = movie.find('span' , class_='rating_num' ).text print (f'电影名字: {title} \t评分: {rating} ' )
豆瓣排名前250标号排序 上面的爬取数据只会有名字还有评分,没有排名,接下来我们继续加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import requestsfrom bs4 import BeautifulSoupheaders = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36' } for page in range (0 , 250 , 25 ): url = f'https://movie.douban.com/top250?start={page} ' response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser' ) movies = soup.find_all('div' , class_='info' ) for idx, movie in enumerate (movies, start=page+1 ): title = movie.find('span' , class_='title' ).text rating = movie.find('span' , class_='rating_num' ).text print (f'排名: {idx} \t电影名字: {title} \t评分: {rating} ' )
在更新后的代码中,我们使用了enumerate()
函数来获得电影的排名。enumerate()
函数会返回一个可迭代对象,同时提供索引和对应的元素。通过设置start=page+1
,我们将排名的起始值设置为当前页面的起始值。
那么,还是不满足在控制台输出结果,想在excel表格里面展示,接下来 Show Time
将其数据导入到excel表格里面 要将数据导入excel中,需要使用第三方库openpyxl
以下是更新后的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import requestsfrom bs4 import BeautifulSoupfrom openpyxl import Workbookheaders = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36' } wb = Workbook() ws = wb.active for page in range (0 , 250 , 25 ): url = f'https://movie.douban.com/top250?start={page} ' response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser' ) movies = soup.find_all('div' , class_='info' ) for idx, movie in enumerate (movies, start=page+1 ): title = movie.find('span' , class_='title' ).text rating = movie.find('span' , class_='rating_num' ).text ws.cell(row=idx, column=1 , value=idx) ws.cell(row=idx, column=2 , value=title) ws.cell(row=idx, column=3 , value=rating) wb.save('douban_top250.xlsx' )
运行完,桌面上就会有一个douban_top250.xlsx
文件,就可以看到
但是
还不是最完美的,他没有第一行作为提示
继续改进
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import requestsfrom bs4 import BeautifulSoupfrom openpyxl import Workbookheaders = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36' } wb = Workbook() ws = wb.active ws['A1' ] = '排名' ws['B1' ] = '电影名字' ws['C1' ] = '评分' for page in range (0 , 250 , 25 ): url = f'https://movie.douban.com/top250?start={page} ' response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser' ) movies = soup.find_all('div' , class_='info' ) for idx, movie in enumerate (movies, start=page+2 ): title = movie.find('span' , class_='title' ).text rating = movie.find('span' , class_='rating_num' ).text ws.cell(row=idx, column=1 , value=idx-1 ) ws.cell(row=idx, column=2 , value=title) ws.cell(row=idx, column=3 , value=rating) wb.save('douban_top250.xlsx' )
使用ws['A1'] = '排名'
将排名列标题写入A1单元格,使用ws['B1'] = '电影名字'
将电影名字列标题写入B1单元格,使用ws['C1'] = '评分'
将评分列标题写入C1单元格。
同时,我们将循环中写入数据的起始行从page+1
修改为page+2
,以便为列标题腾出第一行。
目前就是非常完美了