雙十一購物狂歡節即將到來,作為程序員,利用爬蟲技術查詢商品的歷史價格趨勢,似乎是一個合理的需求,畢竟這只是為了自己參考,不涉及商業用途。然而,小伙伴們在進行爬蟲操作時一定要謹慎小心,尤其是在數據采集和使用的過程中,務必遵守相關法律法規與平臺的使用規范。
每次和大家講解爬蟲時,我總是提醒一句:“謹慎、謹慎、再謹慎!”不僅要避免觸犯法律,也要避免對網站的正常運營造成影響,保持理性和合規。
商品獲取
好的,我們的第一步是進入京東的查詢頁面,找到并打開我們關注的商品頁面。例如,假設我最關注的是顯卡的價格和相關數據,那么接下來我就會去查詢顯卡的具體信息。通過這種方式,我們能夠獲取到顯卡的相關商品數據。如圖:
你要做的工作是找到我們的商品信息請求連接。這個連接可能不好找,所以你需要耐心地逐個查看相關頁面。我已經幫你找到這個連接了,現在我們可以直接根據它開始編寫爬蟲腳本,目標是從中提取商品鏈接。你可以通過右鍵點擊請求,選擇“復制請求為Python代碼”來直接獲取Python代碼。
至于在線工具,市場上有很多類似的工具可以幫助你轉換請求,但我就不一一列舉了,你可以根據需求自行選擇合適的工具。
代碼部分你可以自己編寫,我這里只會提供一些關鍵部分的示例代碼,幫助你更好地理解如何實現。以下是我為你整理的關鍵代碼片段:
response = requests.get('https://api.m.jd.com/', params=params, cookies=cookies, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
div_tags = soup.find_all('div', class_='p-name p-name-type-2')
for div_tag in div_tags:
self_operated_tag = div_tag.find('span', class_='p-tag')
if self_operated_tag and '自營' in self_operated_tag.text:
a_tag = div_tag.find('a', href=True)
product_name = a_tag.find('em').text.strip()
link = 'https:' + a_tag['href'] if a_tag['href'].startswith('//') else a_tag['href']
store.append({
'name': product_name,
'link': link
})
print("名稱:", product_name)
print("鏈接:", link)
else:
print("沒有找到自營標識或沒有相關信息。")
sort_data(store,keyword)
def sort_data(data,name):
with open(name+'.csv','a',newline='',encoding='utf8')as f:
writer=csv.writer(f)
for i in data:
writer.writerow((i['name'],i['link']))
這里我們只關注自營商品,因為自營商品的品質相對有保障。為了避免頻繁爬取導致封號的風險,我將爬取到的數據存儲到了CSV文件中,便于后續使用。畢竟,不建議頻繁地向同一網站發起請求,這樣很容易被封禁。
以下是我爬取的某一頁的數據示例。如果你需要獲取多個頁面的數據,只需調整相關參數即可,確保分頁功能正常工作。爬取的示例數據如下所示:
沒錯,我并沒有爬取商品的實時價格,因為我們這次的主要目標是獲取歷史價格數據。不過,在抓取歷史價格的同時,順便也爬取了商品的最新價格,這樣既能滿足需求,又不會浪費額外的爬取時間。因此,當前的代碼已經覆蓋了這兩方面的內容。
接下來,我們可以轉到另一個網站,看看它的數據結構和爬取方式,以便進行比較和優化。
歷史價格爬取
在成功獲取完當前網站的數據后,我們將轉向爬取另一個網站的數據。首先,為了確保能夠順利抓取到所需的歷史價格信息,我們需要在Web端進行一些初步的測試。通過手動操作和分析網絡請求,我確認了能夠獲取歷史價格數據的請求接口。
經過一番測試和調試后,我成功找到了正確的請求連接。接下來,我將展示這個連接,供大家參考。如下所示:
我們計劃逐步抓取每一個商品鏈接的歷史價格信息,以確保數據的全面性和準確性。然而,在抓取過程中,我注意到請求的內容中包含了一個加密部分,這使得我們無法直接獲取到完整的價格數據。這一加密內容需要解密或進一步處理,才能確保我們能夠成功提取出歷史價格。
因此,在繼續抓取之前,我們需要先分析并處理這個加密機制。以下是加密部分的內容,供參考:
在這個請求過程中,使用的并不是商品的直接鏈接,而是一個經過加密處理的“code”參數。實際上,商品鏈接在上面的請求中已經經歷了一定的轉換處理,因此我們無需過于擔心這個轉換步驟,它只是多了一道處理環節而已,對數據獲取本身沒有實質性影響。
我們只需要按照指定的方式獲取這個“code”參數,并在后續請求中正確使用它即可。經過一系列分析和處理,最終的代碼實現如下所示:
def get_history(itemid):
params = {
'ud': 'EAONJNRXWXSMTBKNNYL_1730899204',
'reqid': '46db0db9f67129f31d1fca1f96ed4239',
'checkCode': 'ada35e4f5d7c1c55403289ec49df69e3P9f1',
'con': itemid,
}
data = {
'checkCode': 'ada35e4f5d7c1c55403289ec49df69e3P9f1',
'con': itemid,
}
response = requests.post('http://www.tool168.cn/dm/ptinfo.php', params=params, cookies=cookies, headers=headers, data=data, verify=False)
code = json.loads(response.text)
params = {
'code': code['code'],
't': '',
'ud': 'EAONJNRXWXSMTBKNNYL_1730899204',
'reqid': '46db0db9f67129f31d1fca1f96ed4239',
}
response = requests.post('http://www.tool168.cn/dm/history.php', params=params, cookies=cookies, headers=headers, verify=False)
pattern = r"Date.UTC\((\d{4}),(\d{1,2}),(\d{1,2})\),([\d\.]+)"
matches = re.findall(pattern, response.text)
prices = []
for match in matches:
year, month, day, price = match
date = datetime(int(year), int(month) + 1, int(day))
prices.append((date, float(price)))
min_price = min(prices, key=lambda x: x[1])
max_price = max(prices, key=lambda x: x[1])
latest_price = prices[-1]
print(f"最低價格: {min_price[1]},日期: {min_price[0].strftime('%Y-%m-%d')}")
print(f"最高價格: {max_price[1]},日期: {max_price[0].strftime('%Y-%m-%d')}")
print(f"最新價格: {latest_price[1]},日期: {latest_price[0].strftime('%Y-%m-%d')}")
get_history("https://item.jd.com/100061261651.html")
最后,通過對獲取到的歷史價格數據進行分析,我們可以基于價格的波動趨勢做出合理的購買判斷!看下最終的效果:
剩下的工作就是對代碼進行優化的過程了。在這個階段,我們的主要目標是展示一個基本的實現思路,并且驗證相關功能是否有效。實際上,我們并不打算爬取所有商品的詳細信息,因為這不僅不符合我們的實際需求,而且在實際操作中也沒有必要。
總結
總的來說,爬蟲技術為我們提供了豐富的數據資源,但在使用過程中,謹慎行事,理性操作,才能真正讓爬蟲技術為我們的生活帶來便利,而不是帶來麻煩。希望大家在即將到來的雙十一購物狂歡節中,既能抓住機會購買心儀的商品,又能遵守道德與法律的底線,做一個負責任的技術使用者。
轉自https://www.cnblogs.com/guoxiaoyu/p/18531125
該文章在 2024/11/12 9:11:03 編輯過