[20240129]
爬虫
爬虫基础
作用
爬虫是数据收集技术,用于模拟人的行为去批量抓取指定数据,再进行处理。
守则
1、不要爬取公民隐私、国家和企业机密、受权限保护的内容;
2、请求数量和频率不可过高
3、不要爬取网站robots里不允许爬取的数据
安装环境
requests HTTP请求库
1、安装pycharm并创建项目
2、在终端输入: pip install requests 或者pip3 install requests --> Successfully installed
bs4 HTML解析库
1、在终端输入:pip install bs4 或pip3 install bs4 --> Successfully installed
openpyxl EXCEL操作库
1、在终端输入: pip install openpyxl 或者pip3 install openpyxl --> Successfully installed
请求头获取
为模仿浏览器发送请求,需要增加请求头,在chrome工具下,查找任意Request Headers --> User-Agent:。将后面的而数据复制粘贴到代码中即可
Chrome 网络开发者工具
在浏览器中按F12以打开工具。
Network
作用:网络请求抓包
数据解析
原理
解析的局部文本内容都会在标签之间或者标签对应的属性中进行存储:
1、定位指定标签(定位)
2、提取标签或标签对应属性中存储的数据值(解析)
3、数据处理完毕后存储至指定格式文件中(保存)
实战1
资料来源
https://mp.weixin.qq.com/s?src=11×tamp=1704783447&ver=5007&signature=eH*gHHl5TedvuFLbCaTO1q-*LIYwjSTNT5HFlCmEhLoel2sk0UKIqNJU0EljR9K59Hg1mOuUOZu4D88i*XdCuMMK1q3SpBs86ikTwcig8LpANtgvT3u8bB3W4iWwmJky&new=1
一、了解HTML和网页结构
在开始编写爬虫之前,了解HTML和网页的结构是非常重要的。HTML是一种标记语言,用来描述网页的结构,它由各种标签(tag)和属性组成。在爬取HTML网页时,我们需要了解网页的结构,明确要爬取的数据所在的标签和属性。
1. DOCTYPE声明:位于网页的顶部,用来指定网页所使用的HTML版本。
2. head部分:位于DOCTYPE声明之后,用来定义网页的元数据和链接外部文件,包括标题(title)、引入CSS样式表、引入JavaScript脚本等。
3. body部分:位于head部分之后,用来定义网页的实际内容。可以包括标题、段落、图片、链接、表格、列表等。
HTML标签通过尖括号(<>)进行标记,有两种类型的标签:起始标签和结束标签。起始标签用来标记元素的开始,结束标签用来标记元素的结束。例如,`
`是一个段落的起始标签,`
`是一个段落的结束标签。
标签可以包含属性,用来提供更多的信息。属性以键值对的形式出现在标签的起始标签中,例如`
`,其中`src`和`alt`就是img标签的属性。
另外,HTML还有一些常见的元素,如链接元素(``)、图片元素(``)、标题元素(`
`到`
`)、列表元素(`
- `、`
- `和`
- `)等,这些元素可以用来构建网页的结构和内容。
- `和`
通过理解HTML和网页的结构,我们可以更好地进行数据爬取。可以通过使用BeautifulSoup库或者查看网页源代码来分析网页的结构,找到我们需要爬取的数据所在的标签和属性,进而进行相应的数据提取。
二、安装并导入库
Python有很多库可以用来进行网页爬取,最常见的是BeautifulSoup库和requests库。我们需要先安装这些库,并在代码中导入它们。
# -*- coding: UTF-8 -*-
import os
import time
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook
三、爬取数据
演示网页地址:重庆有哪些小学 重庆市小学排行榜 重庆市小学名单→买购网
(注:演示地址为真实网页地址,请勿做非法侵入,如有侵权请联系本人删除文章。)
使用requests库可以发送HTTP请求来获取网页的内容。我们可以使用get方法发送一个HTTP GET请求,并将网页的内容保存到一个变量中。
# 创建Excel文件
wb = Workbook()
ws = wb.active
# 爬取地址
url = f'重庆有哪些小学 重庆市小学排行榜 重庆市小学名单→买购网'
# 请求header
header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/112.0.0.0 Safari/537.36',
'cookie': '__yjs_duid=1_b1ac9fc87dce4de5552d7cf0924fb4981686228951567; u=b0281776fd75d3eefeb3562b2a5e6534; '
'__bid_n=1889b14047a51b2b754207; '
'FPTOKEN=qU+ieOMqkW6y6DlsOZ+D/T'
'+SCY6yS3dYvGXKibFoGBijKuUuSbc3ACFDzjlcC18wuDjNLENrw4ktAFAqnl3Akg492Lr4fbvNrkdJ'
'/ZQrluIdklkNDAKYnPrpcbe2H9y7AtX+/b+FCTkSTNv5+qB3OtQQ3BXXsEen72oEoAfK+H6'
'/u6ltZPdyHttJBJiXEDDS3EiUVt+S2w+8ozXENWbNt/AHeCgNUMmdeDinAKCR+nQSGK/twOoTLOU/nxBeSAazg'
'+wu5K8ooRmW00Bk6XAqC4Cb829XR3UinZHRsJxt7q9biKzYQh'
'+Yu5s6EHypKwpA6RPtVAC1axxbxza0l5LJ5hX8IxJXDaQ6srFoEzQ92jM0rmDynp+gT'
'+3qNfEtB2PjkURvmRghGUn8wOcUUKPOqg==|mfg5DyAulnBuIm/fNO5JCrEm9g5yXrV1etiaV0jqQEw=|10'
'|dcfdbf664758c47995de31b90def5ca5; PHPSESSID=18397defd82b1b3ef009662dc77fe210; '
'Hm_lvt_de3f6fd28ec4ac19170f18e2a8777593=1686322028,1686360205; '
'history=cid%3A2455%2Ccid%3A2476%2Ccid%3A5474%2Ccid%3A5475%2Ccid%3A2814%2Cbid%3A3667; '
'Hm_lpvt_de3f6fd28ec4ac19170f18e2a8777593=1686360427'}
response = requests.get(url, headers=header)
time.sleep(0.01)
# print(response)
四、解析信息
通过F12打开网页自带的调试功能,找到需要抓取数据的内容。
通过BeautifulSoup库可以对HTML内容进行解析。我们可以将网页的内容传入BeautifulSoup的构造函数中,并指定解析器。解析后的内容可以通过调用BeautifulSoup对象的方法来访问和过滤。
# 获取网页信息
# soup = BeautifulSoup(response.content, 'lxml')
soup = BeautifulSoup(response.content, 'html.parser')
# print(soup)
# 解析网页数据
# tr_tags = soup.find('div', class_="md_1009 modelbox tcenter").get_text()
tr_tags = soup.find_all('div', class_="md_1009 modelbox tcenter")
# print(tr_tags)
五、提取信息
通过分析网页的结构,我们可以找到要爬取的数据所在的标签和属性。在使用BeautifulSoup库时,可以使用CSS选择器或XPath语法来定位和提取数据。通过调用相应的方法,我们可以获取到所需的数据,例如获取文本内容、获取属性值等。
# 循环遍历获取tr标签下的td标签文本
td_tags = soup.select('tr td')
for i in range(0, len(td_tags), 2):
school_name = td_tags[i].get_text()
address = td_tags[i + 1].get_text()
# score = td_tags[i + 2].get_text()
time.sleep(0.1)
print(f'正在爬取:--{school_name}--{address}--')
# 将数据项转换为一个元组
row = (school_name, address)
# 将数据行写入 Excel 表格
ws.append(row)
六、保存文件
最后,我们可以将爬取到的数据保存到本地文件或数据库中。可以使用Python的文件操作来保存数据到文件中,也可以使用数据库操作库来保存数据到数据库中。
# # 将文件保存到桌面
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
file_path = os.path.join(desktop_path, "学校数据爬取.xlsx")
wb.save(file_path)
打开桌面爬取的Excel数据,我们想要的数据已经全部爬取到Excel文件中了。
图片
七、注意事项
在进行网页爬取时,需要遵守网站的规则和法律法规。不要频繁发送请求,以免给目标网站造成过大的负担。此外,获取到的数据应该进行合法和合规的使用。
八、完整源码
# 1、安装并导入库
# -*- coding: UTF-8 -*-
import os
import time
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook
pass # 这是分隔符
# 2、爬取数据
t1 = time.thread_time()
# 爬取地址
url = f'重庆有哪些小学 重庆市小学排行榜 重庆市小学名单→买购网'
# 请求header,可在网页中按F12查找user-agent以获取
header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/112.0.0.0 Safari/537.36'}
response = requests.get(url, headers=header)
# 3、解析信息
soup = BeautifulSoup(response.content, 'html.parser')
# 4、提取信息
tr_tags = soup.find_all('div', class_="md_1009 modelbox tcenter")
td_tags = soup.select('tr td')
# 创建Excel文件
wb = Workbook()
ws = wb.active
for i in range(0, len(td_tags), 2):
school_name = td_tags[i].get_text()
address = td_tags[i + 1].get_text()
print(f'正在爬取:--{school_name}--{address}--')
row = (school_name, address) # 将数据项转换为一个元组
ws.append(row) # 将数据行写入 Excel 表格
# 5、保存文件
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
file_path = os.path.join(desktop_path, "学校数据爬取.xlsx")
wb.save(file_path)
wb.close() # 关闭文件
use_time = time.thread_time() - t1
print(f"use time : {use_time}")
实战2,正则表达式分析数据
代码思路
1、从网站获取完整网页数据str
2、数据转换成text,查找指定字符串:
(1) findall、.*?搭配使用,查找出所有目标数据list
(2) for循环遍历list,提取目标url
(3) 根据url从网站获取图片数据
(4) 保存数据
完整代码
# 爬虫实战3,正则表达式解析数据
pass # 这是分隔符
# 1、导入库
import os
import requests
import time
import re
t1 = time.thread_time() # 测试开始时间
# 2、爬取数据
url = "搜狗图片搜索 - 上网从搜狗开始"
headers = {
"user-agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36"
}
if not os.path.exists("./img"):
os.mkdir("./img") # 创建图片存储路径
page_Text = requests.get(url,headers=headers)
with open('123.html','wb') as f:
f.write(page_Text.content) # 保存html log
str1 = page_Text.text
# str1 = ('
https://img01.sogoucdn.com/app/a/100520020/8ff759f66f5e475579bb7083f6f958e6" alt style="object-fit: cover; height: 100%">'
# '
https://img01.sogoucdn.com/app/a/100520020/8ff759f66f5e475579bb7083f6f958e6" alt style="object-fit: cover; height: 100%">'
# '
https://img01.sogoucdn.com/app/a/100520020/8ff759f66f5e475579bb7083f6f958e6" alt style="object-fit: cover; height: 100%">')
# 3、提取数据
ex = '
' # .*?为缺省数据代表符号,意思为省略一下数据,以便于批量性查找开头相同,但是中间内容不同的数据
img_src_list = re.findall(ex,str1)
print(f"找到了{len(img_src_list)}个数据")
# 提取完整url,属于分析数据的一环
for i in range(len(img_src_list)):
ex2 = 'https.*?"' # 查找https开头的url数据
img2 = re.findall(ex2,img_src_list[i])
str2 = img2[0].replace('"','') # 把不需要的字符串替换成空字符串
img_data = requests.get(url=str2,headers=headers).content # 在取得完整的image url后,获取图片数据
# 4、保存数据
img_name = str2.split('/')[-1] # 获取image名称
imgPath = 'img\\'+img_name+".png" # image存储路径
with open(imgPath,'wb') as f:
f.write(img_data)
time.sleep(0.001) # 不要太频繁提取数据,否则会被认为是在攻击网站
print(str2)
print(f"use time : {0}",time.thread_time() - t1) # 打印测试耗时
pass # 这是分隔符
总结
正则表达式本质上是定位目标,提取目标,保存目标。
实战3,bs4解析数据
代码思路
1、爬取网页数据str
2、将网页数据str实例化成BeautifulSoup对象Soup。
3、通过Soup.select提取指定标签列表list
4、解析标签列表list中的元素,获得url
5、根据url爬取数据
6、保存数据
前置环境
安装pip install xlml和pip install bs4
完整代码
# 爬虫实战4,bs4解析数据
pass # 这是分隔符
# 1、导入库
import os
import requests
import time
import lxml
from bs4 import BeautifulSoup
t1 = time.thread_time() # 测试开始时间
# 2、爬取数据
url = "搜狗图片搜索 - 上网从搜狗开始"
headers = {
"user-agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36"
}
if not os.path.exists("./img"):
os.mkdir("./img") # 创建图片存储路径
page_Text = requests.get(url,headers=headers)
with open('123.html','wb') as f:
f.write(page_Text.content) # 保存html log
str1 = page_Text.text
# with open('123.html',mode='r',encoding='utf-8') as f:
# str1 = f.read()
# 3、提取数据,正则表达式
soup = BeautifulSoup(str1,"lxml")
pass # 这是分隔符
# list1 = soup.li
# list1 = soup.find('li')
# list1 = soup.find('div',class_='index-left') # ‘div’为目标标签,class_='index-left为目标属性名
# list1 = soup.find_all('img') # 查找所有标签
# list1 = soup.select('a') # 选择所有标签
# list1 = soup.select('.high-quality-list > ul > li > a > img')[0] # 选则路径:.high-quality-list类-->ul标签-->li-->a-->img
# list1 = soup.select('.high-quality-list > ul a')[0].text # 空格表示多个层级,.string为获取该标签下的直系文本,text和get_text为获取所有文本
# list1 = soup.select('.high-quality-list > ul a > img')[0]['src'] # 获取标签内的属性文本(如’href‘、’src‘),如果属性不存在会报错
list1 = soup.select('.high-quality-list > ul > li > a > img')
pass # 这是分隔符
print(f"找到了{len(list1)}个数据")
for i in list1:
i= 'https:'+i['src']
print(i)
img_data = requests.get(url=i,headers=headers).content # 在取得完整的image url后,获取图片数据
# 4、保存数据
img_name = i.split('/')[-1] # 获取image名称
imgPath = 'img\\'+img_name+".png" # image存储路径
with open(imgPath,'wb') as f:
f.write(img_data)
time.sleep(0.05) # 不要太频繁提取数据,否则会被认为是在攻击网站
print(f"use time : {0}",time.thread_time() - t1) # 打印测试耗时
pass # 这是分隔符
实战4 xpath解析数据
代码思路
1、爬取网页数据str
2、将str实例化为extree对象:extree.HTML
3、通过extree.xpath和xpath语句实现提取指定文本。
4、保存文件
前置环境
安装pip install xlml
完整代码
# 爬虫实战5,xpath解析数据
pass # 这是分隔符
# 1、导入库
import os
import requests
import time
from lxml import etree
t1 = time.thread_time() # 测试开始时间
# 2、爬取数据
url = "搜狗图片搜索 - 上网从搜狗开始"
headers = {
"user-agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36"
}
if os.path.exists("./img"):
os.system(f'attrib -r "./img"')
os.remove('./img')
os.mkdir("./img",mode=1) # 创建图片存储路径
# 1.网页爬取
# page_Text = requests.get(url,headers=headers)
# with open('123.html','wb') as f:
# f.write(page_Text.content) # 保存html log
# tree = etree.HTML(page_Text.content) # 导入HTML数据
# 2.本地读取再转换
with open('123.html',mode='r',encoding='utf-8') as f:
str1 = f.read()
tree = etree.HTML(str1) # 导入本地HTML文档
# 3.本地直接读取
# tree = etree.parse('123.html')
# 3、提取数据
# str = tree.xpath('/html/body/div')
# str = tree.xpath('//div[@class="index-left"]') # 使用xpath表达式定位标签,返回为对象;'//'表示多个层级,可以从任意层级开始查找; '@class=""'为属性定位
# str = tree.xpath('//*[@id="content"]//a//text()') # xpath索引是从1开始的;//text()是读取标签的text属性
str = tree.xpath('//*[@id="content"]/div[1]/div/div[1]/ul//img/@src') # @src为读取标签的src的属性
print(str)
print(f"找到了{len(str)}个数据") # @src为查找所有属性为src的标签
for i in str:
i = 'https:' + i
print(i)
img_data = requests.get(url=i,headers=headers).content # 在取得完整的image url后,获取图片数据
# 4、保存数据
img_name = i.split('/')[-1] # 获取image名称
imgPath = 'img\\'+img_name+".png" # image存储路径
with open(imgPath,'wb') as f:
f.write(img_data)
time.sleep(0.05) # 不要太频繁提取数据,否则会被认为是在攻击网站
print(f"use time : {0}",time.thread_time() - t1) # 打印测试耗时
pass # 这是分隔符