爬虫
爬虫概述
应用场景:
1、抓取特定网站或应用的内容,提取出有价值的信息。
2、模拟用户在浏览器或应用中的操作,实现自动化流程。
爬虫是什么
专业术语:网络爬虫(又称网页蜘蛛、网络机器人)
网络爬虫是一种自动按照特定规则抓取网页信息的程序或脚本。
爬虫起源
随着网络的迅猛发展,万维网成为海量信息的载体,如何有效地提取和利用这些信息成为一项巨大挑战。
搜索引擎如Yahoo、Google、百度等,作为帮助人们检索信息的工具,成为用户访问万维网的入口和指南。
网络爬虫是搜索引擎系统中至关重要的组成部分,负责从互联网上收集网页并提取信息。这些网页信息用于建立索引,从而支持搜索引擎的功能。爬虫的性能决定了搜索引擎内容的丰富性和信息的时效性,因此,其优劣直接影响搜索引擎的效果。
爬虫基本原理
爬虫是模拟用户在浏览器或应用中的操作,将这些操作过程实现自动化的程序。
当我们在浏览器中输入一个URL并按下回车时,后台会发生一系列步骤。以输入http://www.baidu.com/为例:
1、查找域名对应的IP地址。
2、向该IP地址对应的服务器发送请求。
3、服务器响应请求,并发回网页内容。
4、浏览器解析网页内容,呈现给用户。
此外,爬虫不仅可以自动完成这些步骤,还能根据预设的规则系统地抓取大量网页信息,提取有用的数据。这在大规模数据分析、市场研究和信息监控等方面具有重要应用。
本质上,网络爬虫就是模拟浏览器的HTTP请求。
浏览器和网络爬虫是两种不同的网络客户端,但它们都以相同的方式获取网页内容。简单来说,网络爬虫的任务就是实现浏览器的功能,通过指定URL直接返回所需的数据,而不需要用户一步步手动操作浏览器来获取。
例如,当网络爬虫访问某个网站时,它会向服务器发送HTTP请求,然后接收和解析服务器返回的网页内容。与浏览器不同的是,爬虫可以自动化地进行这些操作,并按照预设的规则和频率重复执行。这使得爬虫在数据收集和信息提取方面具有很高的效率和可扩展性。
基本流程
1、获取网页:首先要获取网页的源代码。源代码包含了网页上的部分有用信息,只要将其获取下来,就可以从中提取所需的数据。可以使用urllib
、requests
等库来实现HTTP请求操作。
2、解析网页:网页的源代码中包含了许多有用的信息。通过解析源代码,可以提取出这些信息。常用的解析方法包括使用正则表达式、BeautifulSoup
、pyquery
等库来实现网页解析。
3、保存数据:将提取到的有用信息保存到本地或数据库中。可以采用多种方式进行数据存储,比如txt
、csv
、pymysql
、json
、Sqlite
等。这样可以方便地进行后续的数据处理和分析。
爬取猫眼电影排行
目标
提取猫眼电影TOP100的电影名称、时间、评分、图片等信息,并将结果保存为CSV文件,使用Python中的requests
库进行网页请求,使用BeautifulSoup
、lxml
库进行网页解析,并使用pandas
库保存数据。
准备工作
Python>=3.7
requests==2.31.0
pip install requests beautifulsoup4 pandas
目标网站分析
我们需要抓取的目标站点为 http://maoyan.com/board/4,打开之后便可以查看到榜单信息,如下图所示:
排名第一的电影是我不是药神,页面中显示的有效信息有影片名称、主演、上映时间、上映地区、评分、图片等信息。
将网页滚动到最下方,可以发现有分页的列表,直接点击第 2 页,观察页面的 URL 和内容发生了怎样的变化
可以发现页面的 URL 变成 http://maoyan.com/board/4?offset=10,比之前的 URL 多了一个参数,那就是 offset=10,而目前显示的结果是排行 11~20 名的电影,初步推断这是一个偏移量的参数。再点击下一页,发现页面的 URL 变成了 http://maoyan.com/board/4?offset=20,参数 offset 变成了 20,而显示的结果是排行 21~30 的电影。
由此可以总结出规律,offset 代表偏移量值,如果偏移量为 n,则显示的电影序号就是 n+1 到 n+10,每页显示 10 个。所以,如果想获取 TOP100 电影,只需要分开请求 10 次,而 10 次的 offset 参数分别设置为 0、10、20…90 即可,这样获取不同的页面之后,再用正则表达式提取出相关信息,就可以得到 TOP100 的所有电影信息了。
抓取首页
获取第一页的HTML文件
import requests
def get_one_page(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0',
# 当进入到猫眼验证中心时,我们加入cookie,这样我们就可以成功访问猫眼电影了
# 解决猫眼验证中心的问题,后续教学
'Cookie': '__mta=20846343.1722838970361.1722842046227.1722842225582.19; uuid_n_v=v1; uuid=2239842052F311EF8BA6E5594D7FF2C36372693B6C4341208D2CF8B0761FBE8D; _csrf=39368517c4cbbfa876b4577211c7aa9e8c730bfb097f11f72a6e2c13e2c640df; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1722838965; HMACCOUNT=94F56CB31582C7D9; _lxsdk_cuid=19121346269c8-04297c6cdcffbc-4c657b58-232800-19121346269c8; _lxsdk=2239842052F311EF8BA6E5594D7FF2C36372693B6C4341208D2CF8B0761FBE8D; Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2=1722842225; _lxsdk_s=1912134626a-dad-113-f4e%7C%7C37'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
print('请求失败',response.status_code)
return None
url = 'http://maoyan.com/board/4'
html = get_one_page(url)
print(html)
使用BeautifulSoup
库解析返回的HTML文档。
from bs4 import BeautifulSoup
#创建 Beautiful Soup 对象
soup = BeautifulSoup(html)
#格式化输出 soup 对象的内容
print(soup.prettify())
BeautifulSoup定位元素的方法,更多定义内容请查看官方文档:Beautiful Soup 中文文档
# 使用soup获取HTML内容
# 定位元素
# 按照标签查找
print(soup.select("title"))
# 按照类名查找
print(soup.select(".name"))
# 按照id查找
print(soup.select("#app"))
# 组合查找
print(soup.select(".name a"))
在这里我们采用XPath方法来获取文件路径(自己可以试试其他方法,类似的操作步骤)
具体步骤:
1、打开开发者模型(F12),点击上图1位置,可以进行定位
2、点击电影标题成功定位
3、在跳转到的3位置的html代码
4、右键进行复制XPATH路径
通过编写代码方式获取xpath路径所表示的元素
# xPath 索引
from lxml import etree
#利用etree.HTML,将字符串解析为HTML文档
etree_html = etree.HTML(html)
# xpath 路径获取元素的值
title=etree_html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[1]/a')
# //*[@id="app"]/div/div/div[1]/dl/dd[2]/div/div/div[1]/p[1]/a
title
获取title,并通过.text获取其text的值
title=[x.text for x in title]
title
获取一页的数据,这里对XPATH路径进行修改,原来获取单个的使用的dd[2],意思是获取到第二个,我们将[2]去掉表示获取全部。
多://*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[1]/a
单://*[@id="app"]/div/div/div[1]/dl/dd[2]/div/div/div[1]/p[1]/a
下面获取一整页的数据
# 获取一页的数据
def get_one_page_data(html):
etree_html = etree.HTML(html)
# 获取电影图片list
img=[x for x in etree_html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/a/img[2]/@data-src')] # 注意:这里html中是data-src,不是src
title=[x.text for x in etree_html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[1]/a')]
actor=[x.text for x in etree_html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[2]')]
score=[x.text for x in etree_html.xpath('//*[@id="app"]/div/div/div[1]/dl/dd/div/div/div[1]/p[3]')]
return img,title,actor,score
get_one_page_data(html)
循环获取所有数据
from tqdm import tqdm
import time
img_list=[]
title_list=[]
actor_list=[]
score_list=[]
# 获取所有的数据
for i in tqdm(range(0, 10)):
# time.sleep(1)
url="https://www.maoyan.com/board/4?offset="+str(i*10)
html = get_one_page(url)
img,title,actor,score=get_one_page_data(html)
img_list.extend(img)
title_list.extend(title)
actor_list.extend(actor)
score_list.extend(score)
将数据转为DataFrame类型方便保存和清洗
import pandas as pd
data=pd.DataFrame({"img":img_list,"title":title_list,"score":score_list,"actor":actor_list})
data
通关观察可以发现,上映时间为多余字段,其中演员表存在“\n”字符和“主演:”可以去除
按照上述分析进行清洗:
data["score"] = data["score"].str.replace("上映时间:", "")
data["actor"] = data["actor"].str.replace("主演:", "")
data["actor"] = data["actor"].str.replace("\n", "")
data["actor"] = data["actor"].str.replace(" ", "")
data
保存为csv格式
data.to_csv('猫眼电影top100.csv',index=False,encoding='utf-8-sig')