在本文中,我們將探討如何使用Python編寫一個簡單的網絡爬蟲來抓取大衆點評網上的店鋪展示信息。這個項目將涵蓋基本的網絡爬蟲概念和技術,如HTTP請求模擬、網頁解析以及數據存儲。我們的目標是獲取店鋪名稱、地址、評分等信息,以便進行進一步的分析和處理。
準備工作
首先,我們需要安裝必要的庫。你可以通過pip命令來安裝這些依賴項:
pip install requests beautifulsoup4 lxml
此外,你可能還需要設置代理以繞過反爬蟲限制。如果需要使用代理,請確保正確配置了`requests.Session()`對象。
HTTP請求模擬
要開始爬取數據,我們首先需要發送HTTP請求到目標URL(例如店鋪列表頁面)。我們可以使用[Requests](https://pypi.org/project/requests/)模塊來實現這一點:
import requests
def send_request(url):
try:
response = session.get(url, headers=headers)
return response
except Exception as e:
print('Request failed:', str(e))
return None
在這個函數中,我們使用了`session`對象來保持會話狀態,並且設置了相應的頭部(`headers`)來僞裝成瀏覽器訪問。這樣可以幫助我們避免被網站識別爲自動化腳本。
網頁解析
接下來,我們需要從返回的HTML文檔中提取有用信息。這裏我們使用了[BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)庫來進行DOM解析:
from bs4 import BeautifulSoup
def parse_html(response):
if not response or 'content' not in response:
return None
soup = BeautifulSoup(response['content'], 'lxml')
# Extract useful information from the soup object
items = soup.findAll('div', class_='card-list__item')
data = []
for item in items:
shop_name = item.find('a', {'class': 'title'}).text
address = item.find('span', {'class': 'location'}).text
score = item.find('div', {'class': 'rating-box'}).text
data.append({'shop_name': shop_name, 'address': address, 'score': score})
return data
這段代碼假設店鋪信息都包含在一個特定的類名下的元素中。在實際應用中,可能需要更復雜的正則表達式或XPath選擇器來準確地定位所需的數據。
數據存儲
最後,我們需要決定如何保存收集到的數據。最簡單的方法是將結果寫入CSV文件或者數據庫表中。以下是如何將其寫到CSV文件的示例:
import csv
def write_to_csv(data):
with open('shops.csv', 'w', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['shop_name', 'address', 'score'])
writer.writeheader()
for d in data:
writer.writerow(d)
在這個例子中,我們假定已經有了名爲“shops.csv”的空文件。每次運行爬蟲時,都會覆蓋原有的內容並將新的店鋪信息添加進去。
完整的爬蟲腳本
現在我們已經準備好所有的組件,可以組合它們成爲一個完整的爬蟲腳本:
import json
import time
import os
from urllib.parse import urlencode
PROXY_HOST = '' # Your proxy host if needed
PROXY_PORT = '' # Your proxy port if needed
# Set up a session with optional proxy
proxy = {
"http": "http://{}:{}".format(PROXY_HOST, PROXY_PORT),
"https": "http://{}:{}".format(PROXY_HOST, PROXY_PORT),
}
session = requests.Session()
if proxy:
session.proxies = proxy
# Common parameters for URL construction
params = {
'sort': 'distance',
'offset': 0,
'radius': '5km',
'type': 'restaurants',
'cateid': '1',
}
# Initialize headers and other variables
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36',
'Referer': 'https://www.dianping.com/',
'Connection': 'keep-alive',
}
base_url = 'https://www.dianping.com/search?' + urlencode(params)
page_count = int(json.loads(send_request(base_url).json()["msg"])['totalPageCount'])
data = []
# Main loop to fetch pages and process results
for page in range(page_count):
time.sleep(random.uniform(1, 3)) # Random delay between 1 and 3 seconds
url = base_url + '&pn={}'.format(page * 20) # Adjust number of shops per page
res = send_request(url)
if res is not None:
data += parse_html(res)
os.makedirs(os.path.dirname('shops.csv'), exist_ok=True)
write_to_csv(data)
print('Processed page {} out of {}.'.format(page+1, page_count))
請注意,上述代碼僅用於演示目的,實際執行前可能需要調整參數和編碼格式以確保兼容性。在使用之前,請務必遵守相關服務條款和法律法規。