本程序涉及以下方面知識:
1.python鏈接mysql數據庫:http://www.cnblogs.com/miranda-tang/p/5523431.html
2.爬取中文網站以及各種亂碼處理:http://www.cnblogs.com/miranda-tang/p/5566358.html
3.BeautifulSoup使用
4.原網頁數據信息不全用字典的方式,把不存在的字段設置為空
詳細代碼:
#!/usr/bin/python
# -*- encoding:utf-8 -*-
'''
思路:
1.從易迅網爬取冰箱的數據,包括品牌,型號,價格,容積,能效等級,制冷方式,門款式,顯示方式,定頻/變頻,除霜模式,操作方式
2.存入MYSQL數據庫
本次限定為:300L以上的冰箱
環境:win32 python2.7
'''
from bs4 import BeautifulSoup
import requests
import MySQLdb
import datetime
#編碼
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
#連接數據庫,並插入爬到的數據
def insert_db(page_list):
try:
#注意鏈接時加上charset='utf8'解決編碼問題
conn = MySQLdb.connect(user='root', passwd='112233aa',host='192.168.1.14',db='miranda.tang',charset='utf8')
cursor = conn.cursor()
#刪除當日已插入數據,避免重復插入
cursor.execute('DELETE FROM yixun_price_refrigerator WHERE update_day=CURRENT_DATE()')
conn.commit() #提交
#用executemany一次性提交爬取數據,比直接用execute快
sql='INSERT INTO yixun_price_refrigerator values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
cursor.executemany(sql, page_list)
conn.commit() #提交
cursor.close() #關閉cursor
conn.close() #關閉連接
except Exception as e:
print e
conn.rollback()
#得到soup
def urlBS(url):
response=requests.get(url)
soup = BeautifulSoup(response.text,"lxml")
return soup
#得到一共有多少頁
def get_pagenumber(url):
soup=urlBS(url)
page=soup.select('.sort_page_num span')[0]
page_contents=page.contents[1]
pagenumber=int(page_contents.replace('/',''))
return pagenumber
#得到頁面信息
def get_info(product_url):
soup=urlBS(product_url)
# print soup
#get title
title = unicode(soup.title.text.strip().strip(u'【價格_報價_圖片_行情】-易迅網').replace(u'】',''))\
.encode('utf-8').decode('utf-8')
#print title
#get_原價
try:
soup_origin = soup.find("dl", { "class" : "xbase_item xprice xprice_origin" })
price_origin = soup_origin.find("span", { "class" : "mod_price xprice_val" }).\
contents[1].text.encode('utf-8').decode('utf-8')
# print u'原價:' + price_origin
except:
price_origin=0
#pass
#get 現價
try:
soup_sale= soup.find('dl',{'class':'xbase_item xprice'})
price_sale = soup_sale.find("span", { "class" : "mod_price xprice_val" }).contents[1].encode('utf-8').decode('latin1')
#print u'現價:'+ price_sale
except:
price_sale=0
#pass
#得到列名名稱
oup_info_name=soup.find_all('td',{'class':'name'})
# for each in oup_info_name:
# print each.contents[0].encode('utf-8').decode('utf-8')
name_list=[each.contents[0].encode('utf-8').decode('utf-8') for each in oup_info_name]
#得到內容
soup_info_desc=soup.find_all('td',{'class':'desc'})
# for each in soup_info_desc:
#prod_list=[soup_info_desc[0].contents[0].encode('utf-8').decode('latin1')]
prod_list=[each.contents[0].encode("utf-8").decode("utf-8") for each in soup_info_desc] #用列表生成式將原表格中的數據放入列表中
pro_dic={}
pro_list=[today,product_url,title,price_origin,price_sale]
#因為列名爬取數據中不分數據是沒有的,通過字典的方式,把沒有的數據記錄為空
for i in range(len(name_list)):
pro_dic[name_list[i]]=prod_list[i]
name=['品牌','型號','顏色','能效等級','冰箱容積','制冷方式','門款式','重量','尺寸','制冷類型',
'顯示方式','定頻/變頻','除霜模式', '冷凍室溫度區間','冷藏室溫度區間','冰箱冷櫃機型','操作方式']
for each in name:
try:
each=each.encode("utf-8").decode("utf-8")
pro_list.append(pro_dic[each])
# print pro_dic[each]
except:
pro_list.append('')
# print 'null'
# print pro_list
# print len(pro_list)
page_list.append(pro_list)
#得到商品頁鏈接
def get_product_href(url):
soup=urlBS(url)
product_list=soup.select('#itemList .mod_goods_img a')
# print product_list
for i in range(len(product_list)):
pro=product_list[i]
pro_href=pro['href']
# return pro_href
#print pro_href
get_info(pro_href)
if __name__=='__main__':
beseurl='http://searchex.yixun.com/html?path=705882t705892&attr=42515e1o2o3o4o5o6o7'
max_number=get_pagenumber(beseurl)
page_list=[]
today=datetime.date.today() #得到當前日期,插入更新日期
for i in range(1,max_number+1):
# for i in range(1,2):
newurl=beseurl+'&page='+str(i)
#print newurl
get_product_href(newurl)
insert_db(page_list)
print("It's all done")
#建表
# drop table yixun_price_refrigerator;
# CREATE TABLE yixun_price_refrigerator(
# update_day date -- 更新日期
# ,product_url VARCHAR(300) -- 商品鏈接
# ,title VARCHAR(300) -- 名稱
# ,price_origin VARCHAR(100) -- 原價
# ,price_sale VARCHAR(100) -- 現價
# ,Brands VARCHAR(100) -- 品牌
# ,Goods_sn VARCHAR(100) -- 型號
# ,Colour VARCHAR(100) -- 顏色
# ,Energy_efficiency_rating VARCHAR(100) -- 能效等級
# ,Refrigerator_volume VARCHAR(100) -- 冰箱容積
# ,Refrigeration VARCHAR(100) -- 制冷方式
# ,Door_style VARCHAR(100) -- 門款式
# ,weight VARCHAR(100) -- 重量
# ,size VARCHAR(100) -- 尺寸
# ,Cooling_type VARCHAR(100) -- 制冷類型
# ,Display_method VARCHAR(100) -- 顯示方式
# ,frequency VARCHAR(100) -- 定頻/變頻
# ,Defrost_mode VARCHAR(100) -- 除霜模式
# ,Freezer_temperature_range VARCHAR(100) -- 冷凍室溫度區間
# ,Save_temperature_range VARCHAR(100) -- 冷藏室溫度區間
# ,Fridge_freezer_models VARCHAR(100) -- 冰箱冷櫃機型
# ,Operation_method VARCHAR(100) -- 操作方式
# );
結果: