爬虫简单基础

requests

安装requests : 这里我用的是pycharm,在pycharm中打开终端并输入一下代码即可(如果你的环境没出错的话)

# 下载requests
pip install requests

安装好后就可以通过requests获取页面的html源代码

get请求

import requests # 引入requests库

# 将程序发送的请求伪装成浏览器请求
headers={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

# 搜索的网址
url="https://www.baidu.com/"
sc = requests.get(url,headers=headers) # requests包含get请求和post请求
print(sc.text) #显示html代码

 获取header信息,右键鼠标,点击检查,选中网络(NetWork),选择其中一个点击进去拉到最后就可以看到User-Agent 的信息 

 

成功抓取到信息

post请求

以百度翻译为例(目前比较方便找到的post请求)

首先一样的打卡百度翻译,输入要翻译的单词,并打开工具中的网络,并将筛选器锁定到xml(xml主要负责二次请求的,这里区分一下一次请求和二次请求。一次请求即打开页面时进行的请求,二次请求则是通过我们的某些操作进行的二次请求,比如百度翻译中,当我们输入要翻译的单词时,进行了二次请求,并将翻译的结果返回在右边,并且这个过程中没有刷新页面,通常使用的时ajax 请求。还有一些网站会通过二次请求进行一些反爬操作,如一些视频网站,只有当你点击了播放,才会将视频通过二次请求显示出来,在页面的html代码中时找不到的)

 然后定位预览找到我们想要的东西

 定位好后就可以从标头找到url和User-Agentde等信息

 此时情求的网址就变成了上面的url,那么因为这里的post请求是要带差数的,可以从负载里找到提交的表单

 这时就变得简单了,只需要在请求时带上表单数据就可以了

import requests

headers={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

url = "https://cn.bing.com/ttranslatev3?&IG=6E9C35358D4A4624A54C93D3FBA988EA&IID=SERP.5654"

# 表单里的数据
data={
    "fromLang": "en",
    "text": "apple", # 还可以将apple 换成可输入的
    "to": "zh-Hans",
    "token": "zGg0zXz6d0Z2X-O8aRmFyiaNpal7bmSZ",
    "key": "1688022328672",
    "tryFetchingGenderDebiasedTranslations": "true"
}

# get请求的参数是params
sc = requests.post(url,data=data,headers=headers)
print(sc.json()) # 因为返回的json所以用json打开会更容易读懂

 


数据解析

        主要是解析获得的页面源代码,在里面提取到我们所要的信息。

re解析(正则表达式)

  • 正则表达式(这里仅做了解,更为具体的使用方法可以自行了解)
'''
    正则表达式
    
    元字符:
        . (点):匹配除换行符之外的任何字符。
        ^:匹配字符串的开头。
        $:匹配字符串的末尾。
        *:匹配前面的表达式零次或多次。
        +:匹配前面的表达式一次或多次。
        ?:匹配前面的表达式零次或一次。
        |:匹配两个或多个表达式之一。
        []:匹配括号内的任何字符。
        ():分组,用于创建子表达式。
        \ (反斜杠):用于转义其他特殊字符。
        \d:匹配任何十进制数字。
        \w:匹配任何字母数字字符。
        \s:匹配任何空白字符。
        \b:匹配单词边界。
        
    量词:
        *:匹配前面的表达式零次或多次。
        +:匹配前面的表达式一次或多次。
        ?:匹配前面的表达式零次或一次。
        {n}:匹配前面的表达式恰好 n 次。
        {n,}:匹配前面的表达式至少 n 次。
        {n,m}:匹配前面的表达式至少 n 次,但不超过 m 次。

    贪婪匹配和惰性匹配:
        .*:贪婪匹配
        .*?:惰性匹配
        
        在正则表达式中,贪婪和惰性(或称为非贪婪)是描述量词的匹配行为的概念。

        贪婪匹配是指量词尽可能多地匹配,也就是匹配尽可能长的字符串。例如,正则表达式a.*b对于字符串ababab会匹配整个字符串,而不是每个ab单独匹配。
        
        相反,惰性匹配是指量词尽可能少地匹配,也就是匹配尽可能短的字符串。惰性量词可以通过在量词之后添加一个问号 ? 来实现。例如,正则表达式a.*?b对于字符串ababab会匹配第一个ab,而不是整个字符串。
        
        贪婪匹配是正则表达式的默认行为,但有时候我们需要使用惰性匹配来满足特定的需求,比如只匹配最短的字符串。
    

'''
  •         re解析
'''

import re  # 引入re



re.findall(pattern, string):返回字符串中所有匹配指定模式的非重叠子字符串列表。

# 正则前面的r是避免将 \ 识别为转义字符,以下同理
# findall() 方法示例
text = "Hello, my name is John. I love Python."
pattern = r"\w+"
result = re.findall(pattern, text)
print(result)  # 输出:['Hello', 'my', 'name', 'is', 'John', 'I', 'love', 'Python']


re.finditer(pattern, string):返回一个包含所有匹配指定模式的迭代器。每个迭代器对象都表示一个匹配对象。

# finditer() 方法示例
text = "Hello, my name is John. I love Python."
pattern = r"\w+"
iter_result = re.finditer(pattern, text)  # 匹配到的是一个迭代器,可以理解为一个集合
for match in iter_result:
    print(match.group())  # 输出:Hello my name is John I love Python
    

    
# 预加载正则表达式,当正则式很长,但又需要经常使用时的小小优化
obj = re.compile("正则式",re.S) # re.S让.能匹配换行符

# 使用
text = "Hello, my name is John. I love Python."
obj.finditer(text)



以上内容对于html文本的运用

import re

html = """
<span id='abc'>我好可爱<a href='123'>我好强壮</a></span>
"""

obj = re.compile(r"<span id='(.*?)'>(.*?)<a href='(.*?)'>(.*?)</a></span>", re.S)
obj2 = re.compile(r"<span id='(?P<ac>.*?)'>") # 该命名仅能在finditer中使用,为获取到的数据命名,方便查询

res = obj.findall(html)
res2 = obj2.finditer(html) # 迭代器

print(res) # 输出 [('abc', '我好可爱', '123', '我好强壮')]

for ie in res2:
    print(ie.group('ac')) # 输出abc







# 以下了解即可,不常用

re.search(pattern, string):在给定的字符串中搜索匹配指定模式的第一个位置,并返回一个匹配对象,如果没有找到,则返回 None。

# search() 方法示例
text = "Hello, my name is John. I love Python."
pattern = r"love"
result = re.search(pattern, text)
if result:
    print("Match found!")  # 输出:Match found!  
else:
    print("No match!")


re.match(pattern, string):从字符串的开头开始尝试匹配指定模式,如果模式位于字符串的开头,则返回一个匹配对象,否则返回 (匹配对象必须得在开头) None。

# match() 方法示例
text = "Hello, my name is John."
pattern = r"Hello"
result = re.match(pattern, text)
if result:
    print("Match found!")  # 输出:Match found!
else:
    print("No match!")


re.sub(pattern, repl, string):使用给定的替换字符串 (repl) 替换字符串中所有匹配指定模式的子字符串。

# sub() 方法示例
text = "Hello, my name is John."
pattern = r"John"
replace_text = "Alice"
new_text = re.sub(pattern, replace_text, text)
print(new_text)  # 输出:Hello, my name is Alice.


re.split(pattern, string):根据指定模式对字符串进行拆分,并返回拆分后的子字符串列表。

# split() 方法示例
text = "Hi, how are you today?"
pattern = r"\s"  # 使用空格作为分隔符
result = re.split(pattern, text)
print(result)  # 输出:['Hi,', 'how', 'are', 'you', 'today?']



'''

 ***具体使用post还是 get,在页面 检查-> 网络 里会显示


bs4解析

        先下载bs4 (pip install bs4),同样的在终端输入该代码即可

        bs4本质上就是在html文本中通过标签来获取特定的内容

"""

# 引入bs4
from bs4 import BeautifulSoup

# HTML 示例代码
html = '''
<html>
<head>
    <title>Example</title>
</head>
<body>
    <div class="container">
        <h1 class="title">Hello, BeautifulSoup!</h1>
        <ul id="list">
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
        </ul>
        <p class="message">This is a paragraph.</p>
    </div>
</body>
</html>

'''

find:用于查找第一个匹配的元素,并返回该元素或 None。使用方法类似于 find_all,但只返回一个结果。

findAll:用于查找所有匹配的元素,并返回一个列表。可以通过传递标签名称、属性或其他筛选条件来指定要查找的元素。

select:用于使用 CSS 选择器来查找元素。可以根据元素的标签名、类名、id等属性来选择元素。

get:用于获取元素的属性值。传递属性名称作为参数,返回属性的值。

text:用于获取元素的文本内容。返回元素内部的文本字符串,不包括子元素的文本内容。

parent:用于获取元素的父级元素。

previous_sibling 和 next_sibling:用于获取元素的前一个兄弟元素和后一个兄弟元素。


# 创建 BeautifulSoup 对象
soup = BeautifulSoup(html, 'html.parser')

# find 方法示例,查找第一个匹配的元素
title = soup.find('title')
print("find 方法示例:", title.text)

# findall 方法示例,查找所有匹配的元素
items = soup.findAll('li')
for item in items:
    print("find_all 方法示例:", item.text)

# select 方法示例,使用 CSS 选择器来查找元素
message = soup.select('.message')
print("select 方法示例:", message[0].text)

# get 方法示例,获取元素的属性值
container = soup.find('div')
print("get 方法示例:", container.get('class'))

# text 方法示例,获取元素的文本内容
title = soup.find('h1')
print("text 方法示例:", title.text)

# parent、previous_sibling 和 next_sibling 方法示例
ul = soup.find('ul')
parent = ul.parent
previous_sibling = ul.previous_sibling
next_sibling = ul.next_sibling

print("parent 方法示例:", parent)
print("previous_sibling 方法示例:", previous_sibling)
print("next_sibling 方法示例:", next_sibling)

"""

Xpath解析

同样要先下载Xpath(pip install lxml),xpath解析主要是通过层级关来定位到信息的位置(存在相对路径和绝对路径)。

XPath(XML Path Language)是一种用于在 XML 或 HTML 文档中查找和提取信息的语言。它通过路径表达式(类似文件系统路径),在文档中的节点集上进行迭代和筛选,以定位所需的元素或节点。

XPath 的语法结构如下:

  1. 节点选择器:

    • /:从根节点开始选择(绝对路径)
    • //:选择匹配前节点的后代,即选中该节点后面的所有,如div//p,这样会选中div以下的所有p不考虑层级
    • *:通配符,如<div><span><p>,<div><box><p>,这时我想同时取到两个div里面的p ,就可以这样写div/*/p,*表示任意节点
    • text():获取文本,如div/text(),即获取div里面的文本
    • 选取特定的节点内容,如<div>,<div>,<div >,我想仅要第二个div的内容,即div[2]/text(),下标从1开始
    • @:获取属性值,如<a href="123">,我要获取href的值,a/@href
  2. 节点筛选器:

    • element:根据元素名称筛选节点
    • @attribute:根据属性名称筛选节点
  3. 谓语(条件):

    • [@attribute='value']:根据属性值进行节点筛选
    • [position()]:根据节点在节点集中的位置进行筛选
"""
/html/body/div/h1[@class='title']

/html:从根节点开始选择 html 元素
/body:从 html 元素开始选择 body 元素
/div:从 body 元素开始选择 div 元素
/h1[@class='title']:从 div 元素开始选择 class 属性值为 'title' 的 h1 元素

"""

一些基础的反爬

        cookie:

Cookie是一种在Web浏览器中存储数据的小文件。它由服务器发送给浏览器,并由浏览器存储在用户的计算机上。每次浏览器向同一服务器发送请求时,都会将该Cookie发送回服务器,以便服务器可以根据Cookie识别和跟踪用户。比如有一些网站数据你要登录后才能访问,这是就要用到cookie。

  •         直接通过检查,在网络里找到cookie,并将器写在请求头里

"""

import requests

# 直接将cookie写在请求头里 
url = "https://space.bilibili.com/"

head = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
    "Cookie":"buvid3=DA33C5C5-F915-10A7-AF8F-04F5EF3AF8C736806infoc; b_nut=1672797636; i-wanna-go-back=-1; _uuid=F9A24E31-1104F-64107-5D10F-9154452DB710536435infoc; nostalgia_conf=-1; buvid_fp_plain=undefined; rpdid=|(uml~RkY)lk0J'uY~k~m~Y~Y; buvid4=62749559-B849-4443-BD50-5ABC44BA623938045-023010410-nLBHNg1ARt7i4OjXL5%2Banw%3D%3D; hit-dyn-v2=1; LIVE_BUVID=AUTO2716731826285497; CURRENT_BLACKGAP=0; buvid_fp=ff0e8cbefcc5a391f323449df84aef4e; CURRENT_PID=a6ac4980-ce39-11ed-add3-2f8e849e0e4d; hit-new-style-dyn=1; header_theme_version=CLOSE; DedeUserID=351850787; DedeUserID__ckMd5=198430f7bfde7e9e; b_ut=5; FEED_LIVE_VERSION=V_TOPSWITCH_FLEX_5S; fingerprint=ab2a063833a0d30d9d5618e771c57786; CURRENT_QUALITY=112; CURRENT_FNVAL=4048; bp_video_offset_351850787=812491028214841300; share_source_origin=COPY; bsource=share_source_copy_link; PVID=11; b_lsid=1BFC7455_18907615383; innersign=0; SESSDATA=0ef637ce%2C1703599788%2Cb069e%2A62s67SlEbBEl1blQmBK5lSJoJYAyEHDD19rsnHopV14IZfpCW5jMNtVh77UPOH7_K4p8sxFwAAVwA; bili_jct=bd01aab8a1d4844d49f872162f5e5a52; sid=ff07ma7v; home_feed_column=5; browser_resolution=1536-792"
}

src = requests.get(url,headers=head)
print(src.text)

"""
  •  通过session(会话)将登录信息存放起来
"""

# 通过session将登录信息存放起来

import requests

session  = requests.session()

url="https://space.bilibili.com/"

data={
    # 这里面的数据要从 检查-> 网络 里面找
    "userName":"123",
    "password":"456"
}

src = session.get(url) #  这样就将登录的cookie存了起来


"""

防盗链

        有一些视频或图片文件,你能在检查中找到,但单独将网址复制出来就不能打开了,这是因为有防盗链,将referer写到请求头里即可

 ***有一些文件则是在运行网站后通过js生成文件的链接,或者将原文件拆分成很多个小份,仅当用到当前份时才去加载等等很多种操作。这就需要不断练习,积累经验才能解决


ip代理

        当我们需要大规模高效的去爬取数据时,就可以使用代理ip来避免我们自身的ip被封禁。

proxies = {
    "http":"http://代理号端口号",
    "https":"https//代理号端口号"
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值