import html
import requests
from bs4 import BeautifulSoup
import time
import plistlib
from urllib.parse import urljoin # Import urljoin
# Define the base URLs for the pages to scrape
base_urls = [
'https://everymac.com/systems/apple/macbook/',
'https://everymac.com/systems/apple/macbook-air/',
'https://everymac.com/systems/apple/macbook_pro/',
'https://everymac.com/systems/apple/imac/',
'https://everymac.com/systems/apple/imac-pro/',
'https://everymac.com/systems/apple/mac_pro/',
'https://everymac.com/systems/apple/mac_mini/',
'https://everymac.com/systems/apple/mac-studio/',
]
# Define the global user-agent header
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
}
# Function to scrape data from a model page
def scrape_model_page(model_url):
model_data = {}
try:
model_data["Url"] = model_url
response = requests.get(model_url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
# Find the div with id="contentcenter"
contentcenter_div = soup.find('div', id='contentcenter')
if contentcenter_div:
# Extract the heading text and clean it
heading = html.unescape(contentcenter_div.find('h3').text.strip().replace(' Specs', ''))
model_data["Name"] = heading
# Find the div with id="macspecs"
macspecs_div = soup.find('div', id='macspecs')
# Find all the tables within the div
tables = macspecs_div.find_all('table')
for table in tables:
rows = table.find_all('tr')
for row in rows:
cols = row.find_all('td')
if len(cols) >= 2:
key = cols[0].text.replace(":", "").strip()
value = cols[1].text.strip()
model_data[key] = value
if len(cols) >= 4:
key = cols[2].text.replace(":", "").strip()
value = cols[3].text.strip()
model_data[key] = value
assert('Apple Model No' in model_data and 'Model ID' in model_data)
except Exception as e:
print(f"Error scraping data for {model_url}: {e}")
return None
return model_data
# Main function to fetch data for all years and models
def main():
years_data = []
for base_url in base_urls:
response = requests.get(base_url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
# Find all span elements with id starting with "contentcenter_specs_externalnav_2"
span_elements = soup.find_all('span', id=lambda x: x and x.startswith('contentcenter_specs_externalnav_2'))
for span_element in span_elements:
# Check if the span element contains a link
link = span_element.find('a', href=True)
if link:
model_url = urljoin(base_url, link['href'])
print(f"Scraping data for {model_url}...")
model_data = scrape_model_page(model_url)
years_data.append(model_data)
time.sleep(5) # Sleep for 5 seconds to avoid overloading the server
# Save the data to a plist file
with open('Systems.plist', 'wb') as plist_file:
plistlib.dump(years_data, plist_file)
if __name__ == "__main__":
main()