网络爬虫基础

什么是爬虫?

通过编写程序,模拟浏览器(原始天然的爬虫工具)上网,然后让其去互联网上抓取数据(页面或部分数据)的过程

爬虫的价值:抓取数据、将数据产生价值、就业爬虫工程师

浏览器工具:

elements:是shell脚本执行后的html代码

network:网络请求抓包,记录浏览器发送给服务器的所有网络请求

source:网站中的图片资源、脚本等

requests模块

功能强大、操作简单、效率极高

作用:模拟浏览器发请求

爬取步骤(编码流程):

—指定url网址

—get(url)或者post(url)发起请求,返回响应对象:服务器返回页面源代码或者数据,浏览器执行显示页面

—text获取响源代码、json获取json数据

—with open持久化存储

 #获取百度页面的源代码
 import requests
 url="http://www.baidu.com/"
 response=requests.get(url)#返回响应对象
 response.encoding="UTF-8"
 print(response.text)
 with open("mybaidu.html",mode='w',encoding="UTF-8") as f:
     f.write(response.text)

get请求

#输入翻译内容获取翻译数据
 import requests
 url="https://fanyi.baidu.com/sug"
 data={
     "kw":input("请输入您要翻译的内容:")
 }
 response=requests.post(url,data=data)
 print(response.json())

post请求

如果返回的是json,可以直接拿到json数据

 #输入关键字获取附近肯德基餐厅的信息
 import requests
 url="https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword"
 data={
     "cname" : "",
     "pid": "",
     "keyword": input("请输入餐厅关键字:"),
     "pageIndex": "1",
     "pageSize": "10"
 }
 response=requests.post(url,data=data)
 print(response.json())

正则表达式

作用:匹配字符串的一门表达式语言

测试方式:在线正则表达式测试

正则支持普通字符(26个字母、文字)

元字符

用一个符号来匹配对应类型数据

\d:匹配一个数字(0-9)

\w:匹配数字、字母、下划线(0-9,a-z,A-Z,__)

\D:相对于\d取反(匹配除了数字以外的)

\W:相对于\w取反

[内容]:字符组、匹配指定内容

[^内容]:字符组匹、配除了指定内容以外的

. 匹配除了换行符以外的所有内容

量词

控制元字符出现的频次

+:前面的元字符出现一次或多次

*:前面的字符出现0次或多次(贪婪机制:尽可能多匹配结果)

?:前面的字符出现0次或一次

惰性匹配

.*?:匹配到距离xxx最近的xxx的内容

.*:匹配到距离xxx最远的xxx的内容

 匹配文本:玩儿吃鸡游戏,晚上一起上游戏,干嘛呢?打游戏啊
 正则表达式:玩儿.*游戏
 匹配结果:玩儿吃鸡游戏,晚上一起上游戏,干嘛呢?打游戏(最远,尽可能多匹配)
 正则表达式:玩儿.*?游戏
 匹配结果:玩儿吃鸡游戏(最近,尽可能少匹配)

内置模re

 import re
 result=re.findall(r"\d+","今天我有100块,买了2个蛋糕")#返回一个匹配结果列表
 result=re.search(r"\d+","今天我有100块,买了2个蛋糕")#返回一个匹配对象,存储第一次匹配的内容
 print(result.group())#输出匹配的内容
 result=re.finditer(r"\d+","今天我有100块,买了2个蛋糕")#返回一个匹配对象迭代器
 for item in result:
     print(item.group())#从match对象中拿到数据,需要group()

re.findall()

re.search()

re.finditer()

预加载

让正则和数据分开,使代码结构清晰

 import re
 obj=re.compile(r"\d+")#提前加载好一个正则
 obj.findall("字符串")
 obj.search("字符串")
 obj.finditer("字符串")
 import re
 s="""
 <div class="abc">
     <div><a href="baidu.com">我是百度</a></div>
     <div><a href="qq.com">我是腾讯</a></div>
     <div><a href="163.com">我是网易</a></div>
 </div>
 """
 #compile预加载、(?P<>)起别名
 obj=re.compile(r'<div><a href="(?P<url>.*?)>(?P<txt>.*?)</a></div>')
 result=obj.finditer(s)
 for item in result:
     url=item.group("url")
     txt=item.group("txt")
     print(url,txt)
     print(item.groupdict())#返回别名:匹配文本的字典

re.compile()

(?P<name>.*?)起别名

爬虫大案例:

#抓取的信息在网页源代码里
#目标:豆瓣top250电影信息(名称、发布日期、地区、类型、评分、评价人数),并存储至csv文件
#思路:1.拿到页面源代码2.使用re提取数据3.存储到csv文件中
import requests
import re
import pandas

movie_names = []
movie_scores = []
movie_location= []#统计
movie_type= []#统计
movie_years= []#统计
movie_nums= []

for i in range(1,11):
    page=(i-1)*25
    url=f"https://movie.douban.com/top250?start={page}&filter="
    #因此应修改为浏览器的请求头
    header={
        #UA伪装,服务器对当前的网络设备进行检测
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
    }
    response=requests.get(url,headers=header)
    response.encoding="utf-8"
    #处理反爬
    #print(response.request.headers)#python程序的请求头默认为{'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}

    obj=re.compile(r'<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?<br>'
                    r'(?P<year>.*?)&nbsp;/&nbsp;(?P<nation>.*?)&nbsp;/&nbsp;(?P<type>.*?)'
                        r'</p>.*?<span class="rating_num" property="v:average">'
                    r'(?P<score>.*?)</span>.*?<span>(?P<num>.*?)人评价',re.S)

    result = obj.findall(response.text)
    for item in result:
        movie_names.append(item[0])
        year = item[1].strip()
        movie_years.append(year)
        movie_location.append(item[2])
        type=item[3].strip()
        movie_type.append(type)
        movie_scores.append(item[4])
        movie_nums.append(item[5])
# print("电影名:", movie_names)
# print("发布年限:", movie_years)
# print("地区:", movie_location)
# print("类型:", movie_type)
# print("评分列表:", movie_scores)
# print("评价人数:", movie_nums)

data = {
    "电影名称": movie_names,
    "发布年限": movie_years,
    "地区":movie_location,
    "类型":movie_type,
    "评分": movie_scores,
    "评分人数": movie_nums
}
df = pandas.DataFrame(data)
# 将DataFrame保存为CSV文件
df.to_csv("电影信息.csv",index=False)

.*?:过滤信息

(?P<cotent>.*?):提取目标信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值