python爬數據[簡易版]
對于每個網站的爬的原理基本是一樣的,但是具體的代碼寫法的區別就在于爬的數據中解析出想要的數據格式:
以爬取有道詞典中的圖片為例:
第一步:打開網站,分析圖片的數據源來自哪里,
https://dict-subsidiary.youdao.com/home/content?invalid=&previewEnvTest=
發現我們要的數據原來自這里,
{"data": {.....略....."secondList": [{"name": "網易有道詞典APP","picture": "https://ydlunacommon-cdn.nosdn.127.net/4e7ca43db1a83f11c467105181e9badb.png","desc": "智能學習更高效","buttonList": [{"text": "下載","type": 0,"url": "https://cidian.youdao.com/download-app/"}]},{"name": "有道詞典筆","picture": "https://ydlunacommon-cdn.nosdn.127.net/c30638638a393dc38464600caf4888fb.jpg","desc": "更專業的詞典筆","buttonList": [{"text": "查看詳情","type": 0,"url": "https://smart.youdao.com/dictPenX6Pro"}]},......略....
}
接下來就是分析返回的數據,解析數據~拿出圖片的url
response = requests.get(url, headers)
# response = request.urlopen(url).read()
# 處理數據json_load = json.loads(response.text)
# json_load = json.loads(response)
dt = json_load['data']
dumps = json.dumps(dt)
loads = json.loads(dumps)
listS = loads["secondList"]
arr = []
for i in listS:json_dumps = json.dumps(i)json_loads = json.loads(json_dumps)arr.append(json_loads["picture"])
爬取數據:
i = 0
for item in arr:requests_get=request.urlopen(item).read()png = "d:/PythonData/pic/" + str(i) + ".png"with open(png, "wb") as f:f.write(requests_get)i = i + 1
完整的代碼:
from urllib import request
import re
import requests
import json
"""爬取有道詞典的圖片
"""
url = "https://dict-subsidiary.youdao.com/home/content?invalid=&previewEnvTest="
headers = {# User-Agent 用戶代理 瀏覽器基本身份信息'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 ''Safari/537.36'
}
response = requests.get(url, headers)
# response = request.urlopen(url).read()
# 處理數據
json_load = json.loads(response.text)
# json_load = json.loads(response)
dt = json_load['data']
dumps = json.dumps(dt)
loads = json.loads(dumps)
listS = loads["secondList"]
arr = []
for i in listS:json_dumps = json.dumps(i)json_loads = json.loads(json_dumps)arr.append(json_loads["picture"])
i = 0
for item in arr:requests_get=request.urlopen(item).read()png = "d:/PythonData/pic/" + str(i) + ".png"with open(png, "wb") as f:f.write(requests_get)i = i + 1
example:
"""
# 導入數據請求模塊 --> 第三方模塊, 需要安裝 pip install requests
# 導入正則模塊 --> 內置模塊, 不需要安裝
"""
import requests
import re"""
1.
發送請求, 模擬瀏覽器對于url地址發送請求
- 模擬瀏覽器 < 反爬處理 > 請求頭 < 字典數據類型 >
如果你不偽裝, 可能會被識別出來是爬蟲程序, 從而得到數據內容
可以直接復制粘貼 --> 開發者工具里面就可以復制- < Response[200] > 響應對象
Response: 中文意思 -->響應
<>: 表示對象
200: 狀態碼
表示請求成功
發送請求, 請求成功了分析請求url地址變化規律:
第一頁: http: // www.netbian.com / dongman /
第二頁: http: // www.netbian.com / dongman / index_2.htm
第三頁: http: // www.netbian.com / dongman / index_3.htm
第四頁: http: // www.netbian.com / dongman / index_4.htm"""
for page in range(2, 11):print(f'=================正在采集第{page}頁的數據內容=================')# 請求圖片目錄頁面urlurl = f'http://www.netbian.com/dongman/index_{page}.htm'# 偽裝模擬成瀏覽器headers = {# User-Agent 用戶代理 瀏覽器基本身份信息'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'}# 發送請求# 調用requests模塊里面get請求方法, 對于url地址發送請求, 并且攜帶上headers請求頭偽裝, 最后用自定義變量名response接受返回的數據response = requests.get(url=url, headers=headers)"""
2.
獲取數據, 獲取服務器返回響應數據
response
網頁源代碼
response.text
獲取響應文本數據 < 網頁源代碼 >
3.
解析數據, 提取我們想要的數據內容
- 圖片ID
正則表達式Re
會1
不會0
調用re模塊里面findall方法 --> 找到所有我們想要的數據
re.findall('找什么數據', '從哪里找') --> 從什么地方, 去匹配找什么樣的數據內容
從
response.text < 網頁源代碼 > 里面
去找 < a
href = "/desk/(\d+).htm"
其中(\d +) 就是我們要的內容
\d + 表示任意數字
"""
# 提取圖片ID --> 列表 <盒子/箱子> '29381' 是列表<箱子>里面元素<蘋果>
img_id_list = re.findall('<a href="/desk/(\d+).htm"', response.text)
# for循環遍歷, 把列表里面元素 一個一個提取出來
for img_id in img_id_list:# img_id變量<袋子> 給 img_id_list 列表<盒子> 里面 元素<蘋果> 給裝起來print(img_id)"""
4.
發送請求, 模擬瀏覽器對于url地址發送請求
- 請求
圖片詳情頁頁面url
http: // www.netbian.com / desk / {圖片ID}.htm
5.
獲取數據, 獲取服務器返回響應數據
response
網頁源代碼
"""# 請求詳情頁鏈接 --> f'{img_id}' 字符串格式化方法link = f'http://www.netbian.com/desk/{img_id}.htm'# 發送請求response_1 = requests.get(url=link, headers=headers)# 獲取數據內容 網頁源代碼 ---> 亂碼了, 進行轉碼response_1.encoding = 'gbk'# 6. 解析數據, 提取我們想要的數據內容<圖片鏈接/圖片標題>img_url, img_title = re.findall('<img src="(.*?)" alt="(.*?)"', response_1.text)[0]# 7. 保存數據 --> 先獲取圖片數據內容img_content = requests.get(url=img_url, headers=headers).contentwith open('img\\' + img_title + '.jpg', mode='wb') as f:f.write(img_content)print(img_url, img_title)
python中的拷貝
import copy
from typing import override"""對于簡單的 object,用 shallow copy 和 deep copy 沒區別"""
"""構造一個類,然后構造一個實例,然后拷貝這個實例,就會發現,淺拷貝和深拷貝效果一樣"""
"""如果是拷貝的list,深拷貝會拷貝list里面的內容,淺拷貝不會拷貝list里面的內容,而是拷貝list的地址""""""淺拷貝"""class Dog(object):def __init__(self, name):self.name = name"""如果要求名一樣就是一個,那么需要重寫下面的方法## def __eq__(self, other):# return self.name == other.name## def __gt__(self, other):# return self.name > other.name"""a = Dog("a")copy_obj_dog = copy.copy(a)deep_copy_obj_dog = copy.deepcopy(a)print(copy_obj_dog) # <__main__.Dog object at 0x000002A0BFA56210>
print(deep_copy_obj_dog) # <__main__.Dog object at 0x000002A0BFA56ED0>
print(copy_obj_dog == deep_copy_obj_dog) # FALSE# 修改其中的一個,修改深拷貝的對象不影響源對象
deep_copy_obj_dog.name = "b"
print(copy_obj_dog.name) # a
print(deep_copy_obj_dog.name) # b
print(a.name) # a
"""深拷貝"""class Cat:def __init__(self, name):self.name = namec = Cat("c")
copy_obj_cat = copy.copy(c)
deep_copy_obj_cat = copy.deepcopy(c)copy_obj_cat.name = "d"
print(copy_obj_cat.name) # d
print(deep_copy_obj_cat.name) # c
print(c.name) # c# 可以看到淺拷貝跟深拷貝對于簡單的obj對象,效果是一樣的,都是拷貝到一個新對象中cat = Cat("list")
arr = [cat]
# 淺拷貝list~復雜對象 此時淺拷貝考的是地址
copy_arr = copy.copy(arr)
print(copy_arr == arr) # Trueprint(arr[0])
print(copy_arr[0])# 修改list中的一個,修改淺拷貝的對象會影響源對象
copy_arr[0].name = "修改了"
print(arr[0].name)# 深拷貝~list 修改不會影響源對象
cat2 = Cat("list2")
arr2 = [cat2]deepcopy_arr2 = copy.deepcopy(arr2)
print(deepcopy_arr2 == arr2)print(arr2[0])
print(deepcopy_arr2[0])deepcopy_arr2[0].name = "change"
print(arr2[0].name)"""淺拷貝list中填充的是地址"""
"""深拷貝list中填充的是原始對象的副本"""class CustomCopy():"""自定義復制行為"""def __init__(self, name):self.name = namedef __copy__(self):print("copy")return CustomCopy(self.name)def __deepcopy__(self, memo):print("deepcopy")return CustomCopy(copy.deepcopy(self.name, memo))a = copy.copy(CustomCopy("a"))
ab = copy.deepcopy(CustomCopy("a"))
print(a == ab)