PYTHON實(shí)戰(zhàn)計(jì)劃第二周實(shí)戰(zhàn)作業(yè):爬取10萬商品數(shù)據(jù)

成果展示

詳情頁鏈接


Paste_Image.png

商品信息

Paste_Image.png

我的代碼

主函數(shù)(main.py)

#-*- coding:utf-8 -*-
from multiprocessing import Pool
from channel_extact import channel_list
from ganji_url_info import get_url_link,url_links,get_goods_info,goodsinfo

#斷點(diǎn)續(xù)傳判斷
download_Y = [item['url'] for item in goodsinfo.find()] # 相關(guān)鏈接數(shù)據(jù)已下載至數(shù)據(jù)庫(kù)
download_N = [item['url'] for item in url_links.find()] # 完整數(shù)據(jù)鏈接
Y = set(download_Y) #集合化
N = set(download_N) #集合化
need_to_download = N-Y  # 還未下載的鏈接

#def get_all_links(channel):
#    for page in range(1,101):
#        get_url_link(channel,page)


if __name__ == '__main__':
    # 利用多進(jìn)程來爬取
    #pool = Pool()
    #pool.map(get_url_link,channel_list)
    #pool.map(get_goods_info,need_to_download)
    #pool.close()
    #pool.join()

    #不用pool逞带,直接爬取
    #for url in need_to_download:
    #    get_goods_info(url)


獲取代理(My_proxies.py)

import requests
from bs4 import BeautifulSoup
import random

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36',
    'Connection': 'keep-alive',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, sdch',
}


def get_proxies():
    url = 'http://www.xicidaili.com/nn'
    proxies_list = []  # 存儲(chǔ)代理IP
    wb_data = requests.get(url, headers=headers).text
    soup = BeautifulSoup(wb_data, 'lxml')
    ips = soup.select('tr.odd > td:nth-of-type(2)')  # ip地址
    ports = soup.select('tr.odd > td:nth-of-type(3)')  # 端口號(hào)
    speeds = soup.select('tr > td:nth-of-type(7) > div > div')  # 速度
    connect_times = soup.select('tr > td:nth-of-type(8) > div > div')  # 連接速度
    # 信息合并喧兄,且篩選出速度快的代理
    for ip, port, speed, connect_time in zip(ips, ports, speeds, connect_times):
        if speed.get('class')[1] == 'fast' and connect_time.get('class')[1] == 'fast':
            proxies_list.append('http://' + str(ip.text) + ':' + str(port.text))
        else:
            continue
    print(proxies_list)

get_proxies()

取得分類鏈接 (channel_extact.py)

# -*- coding:utf-8 -*-
from bs4 import BeautifulSoup
import requests


url = 'http://bj.ganji.com/wu/'
url_host = 'http://bj.ganji.com'

def get_channel_link(url):
    wb_data = requests.get(url)
    soup = BeautifulSoup(wb_data.text,'lxml')
    channel_links = soup.select('dl.fenlei > dt > a')
    #print(channel_links)
    for channel in channel_links:
        print(url_host + channel.get('href'))

channel_list ='''
    http://bj.ganji.com/jiaju/
    http://bj.ganji.com/rirongbaihuo/
    http://bj.ganji.com/shouji/
    http://bj.ganji.com/bangong/
    http://bj.ganji.com/nongyongpin/
    http://bj.ganji.com/jiadian/
    http://bj.ganji.com/ershoubijibendiannao/
    http://bj.ganji.com/ruanjiantushu/
    http://bj.ganji.com/yingyouyunfu/
    http://bj.ganji.com/diannao/
    http://bj.ganji.com/xianzhilipin/
    http://bj.ganji.com/fushixiaobaxuemao/
    http://bj.ganji.com/meironghuazhuang/
    http://bj.ganji.com/shuma/
    http://bj.ganji.com/laonianyongpin/
    http://bj.ganji.com/xuniwupin/
'''
#以下三項(xiàng)分類格式與上面的不統(tǒng)一
#http://bj.ganji.com/qitawupin/
#http://bj.ganji.com/ershoufree/
#http://bj.ganji.com/wupinjiaohuan/

#get_channel_link(url)

取各分類鏈接列表并取得詳情頁信息(ganji_url_info.py)

# -*- coding:utf-8 -*-
from bs4 import BeautifulSoup
import requests
import pymongo
import time , random
import requests.exceptions


client = pymongo.MongoClient('localhost', 27017)
ganji = client['ganji']
url_links = ganji['url_links_2']
url_links_zz = ganji['url_links_zz_2']
goodsinfo = ganji['goodsinfos']

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36',
    'Connection': 'keep-alive',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, sdch',
}

# http://www.xicidaili.com/wn
proxy_list =['http://121.193.143.249:80',
             'http://42.159.251.84:41795',
             'http://119.6.136.122:80',
             'http://101.201.235.141:8000',
             'http://118.180.15.152:8102',
             'http://123.57.190.51:7777'
    ]
proxy = random.choice(proxy_list) # 隨機(jī)選擇代理
proxies = {'http': proxy}

#爬取網(wǎng)頁鏈接
def get_url_link(channel, page, who_sells='o'):
    try:
        url_link = '{}{}{}/'.format(channel, str(who_sells), str(page))
        wb_data = requests.get(url_link, headers=headers)
        time.sleep(1)
        soup = BeautifulSoup(wb_data.text, 'lxml')
    except (requests.exceptions.ProxyError, requests.exceptions.ConnectionError,requests.exceptions.ReadTimeout) as e:
        print('This is a error raise')


    # 判斷該網(wǎng)頁是否有效
    url_right = soup.select('ul.pageLink.clearfix') == []
    if url_right:
        pass
    else:
        data_1 = soup.select('li.js-item > a')  # 趕集網(wǎng)相關(guān)鏈接信息所在
        #print(data_1)
        data_2 = soup.select('div.zz-til > a')  # 58轉(zhuǎn)轉(zhuǎn)相關(guān)鏈接信息所在
        # 將標(biāo)題及對(duì)應(yīng)鏈接存入url_links
        for data in data_1:
            if 'biz.click.ganji.com' not in data.get('href'):
                url_links.insert_one({'title': data.get_text(strip=True), 'url': data.get('href')})
                print({'title': data.get_text(strip=True), 'url': data.get('href')})
        # 將標(biāo)題及對(duì)應(yīng)鏈接存入url_links_zz
        for data in data_2:
            url_links_zz.insert_one({'title': data.get_text(strip=True), 'url': data.get('href')})
            # print({'title': data.get_text(strip=True), 'url': data.get('href').split('?')[0]})


#爬取詳情信息
def get_goods_info(url):
    try:
        wb_data = requests.get(url, headers=headers, proxies=proxies).text
        soup = BeautifulSoup(wb_data, 'lxml')
        # 判斷頁面是否正常荒辕,若頁面商品信息已刪除或無效硼莽,跳過
        if soup.select('div.error'):
            print(url)
            print('This page is Not Found!')
        else:
            title = soup.select('h1.title-name')[0].get_text() if soup.select('h1.title-name') else None  # 標(biāo)題
            # 發(fā)布時(shí)間
            if soup.select('i.pr-5'):
                published = soup.select('i.pr-5')[0].get_text(strip=True)
            else:
                published = None
            goods_types = soup.select('div > ul.det-infor > li:nth-of-type(1) > span > a')
            goods_type = [i.get_text(strip=True) for i in goods_types]  # 商品類型
            locations = soup.select('div > ul.det-infor > li:nth-of-type(3) > a')
            location = [i.get_text(strip=True) for i in locations]  # 交易地點(diǎn)
            price = soup.select('i.f22.fc-orange.f-type')[0].get_text() \
                if soup.select('i.f22.fc-orange.f-type') else None  # 價(jià)格
            if len(soup.select('body > div > div > div.h-crumbs > div > a')) >= 3:
                classfy = soup.select('body > div > div > div.h-crumbs > div > a')[2].text
            else:
                classfy = None
            # 判斷是否有該字段值
            if soup.find(text='新舊程度:'):
                degree = soup.select('ul.second-det-infor.clearfix > li')[0].get_text().split()[-1]  # 新舊程度
            else:
                degree = None

            #print(title,published,goods_type,location,price,classfy)
            # 保存數(shù)據(jù)至數(shù)據(jù)庫(kù)
            # 爬取不到關(guān)鍵信息束铭,信息不入數(shù)據(jù)庫(kù),待下次處理
            if title or published or price:
                goodsinfo.insert_one({'title': title,
                                      'published': published,
                                      'goods_type': goods_type,
                                      'location': location,
                                      'price': price,
                                      'degree': degree,
                                      'url': url,  # 用于后面判斷還未下載的鏈接,
                                      'classfy': classfy
                                      })
                print(
                    {'title': title,
                     'published': published,
                     'goods_type': goods_type,
                     'location': location,
                     'price': price,
                     'degree': degree,
                     'url': url,
                     'classfy': classfy
                     }
                )
            else:
                pass
    except (requests.exceptions.ProxyError, requests.exceptions.ConnectionError,requests.exceptions.ReadTimeout) as e:
        print('This is a error raise')



#url='http://bj.ganji.com/yingyouyunfu/2285918732x.htm'
#get_goods_info(url)

總結(jié):

  1. 設(shè)計(jì)過程中不斷的遇到問題拾稳,不斷的在代碼添加新功能解決寸宏,使程序盡量完善,主要問題如下:
    |- 同一IP訪問次數(shù)過多土砂,被網(wǎng)站封了州既,設(shè)計(jì)了一個(gè)從代理網(wǎng)站獲取代理IP的程序,來解決代理IP的問題萝映;
    |- 爬取過程中各種請(qǐng)求失效吴叶,超時(shí)等報(bào)錯(cuò)影響程序運(yùn)行的連續(xù),利用try-except序臂,將此種報(bào)錯(cuò)獲取蚌卤,暫時(shí)跳過此網(wǎng)頁,繼續(xù)往下運(yùn)行贸宏,后面再來處理這些未成功的網(wǎng)頁
    |- 加入了判斷頁面已失效(404)或 頁面內(nèi)容讀取失敗的判斷造寝,跳過這些頁面磕洪,增加效率
    |- 爬取的詳情頁鏈接中吭练,存在許多跳轉(zhuǎn)到轉(zhuǎn)轉(zhuǎn)的鏈接,將此類鏈接另外存于Mongo的另一集合中析显,因頁面不同鲫咽,如需獲得這些鏈接的詳情,需另設(shè)計(jì)函數(shù)來獲取此類鏈接詳情信息
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谷异,一起剝皮案震驚了整個(gè)濱河市分尸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌歹嘹,老刑警劉巖箩绍,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異尺上,居然都是意外死亡材蛛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門怎抛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卑吭,“玉大人,你說我怎么就攤上這事马绝《股停” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)掷邦。 經(jīng)常有香客問我白胀,道長(zhǎng),這世上最難降的妖魔是什么抚岗? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任纹笼,我火速辦了婚禮,結(jié)果婚禮上苟跪,老公的妹妹穿的比我還像新娘廷痘。我一直安慰自己,他們只是感情好件已,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布笋额。 她就那樣靜靜地躺著,像睡著了一般篷扩。 火紅的嫁衣襯著肌膚如雪兄猩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天鉴未,我揣著相機(jī)與錄音枢冤,去河邊找鬼。 笑死铜秆,一個(gè)胖子當(dāng)著我的面吹牛淹真,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播连茧,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼核蘸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了啸驯?” 一聲冷哼從身側(cè)響起客扎,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎罚斗,沒想到半個(gè)月后徙鱼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡针姿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年袱吆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搓幌。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杆故,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出溉愁,到底是詐尸還是另有隱情处铛,我是刑警寧澤饲趋,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站撤蟆,受9級(jí)特大地震影響奕塑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜家肯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一龄砰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讨衣,春花似錦换棚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至歹茶,卻和暖如春夕玩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惊豺。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工燎孟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尸昧。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓揩页,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親彻磁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子碍沐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,318評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)衷蜓,斷路器,智...
    卡卡羅2017閱讀 134,714評(píng)論 18 139
  • 出現(xiàn)的問題: 當(dāng)爬取交易地點(diǎn)尘喝,使用代碼 時(shí)磁浇,爬取的結(jié)果是 ['交易地點(diǎn):'],而不是我想要的‘地點(diǎn)-地點(diǎn)’形式 ...
    鳴人吃土豆閱讀 1,312評(píng)論 1 0
  • 伐伐Eve閱讀 304評(píng)論 4 15
  • 坎尼克健康中心的雙塔與著名的悉尼歌劇院朽褪,隔著悉尼灣遙遙相對(duì)置吓,是巖石區(qū)乃至整個(gè)新南威爾士州最高的建筑。 走過了悉...
    兜里有鐵閱讀 270評(píng)論 0 0