石头的作业~第一周实战作业:爬取一页商品数据

实战计划0430-石头的练习作业

练习的要求

爬取列表页
爬取详情页

效果如下:

实现效果

实现的代码

__author__ = 'daijielei'

'''
    14课时练习:
    1、抓取58同城的列表页中的除转转和推广商品外的全部列表内容
    2、抓取详情页里的各项信息内容


!!!未完全实现该部分功能,抓取浏览量因为该部分由JS控制,目前找到的方法无效
'''

#requests用于抓取html页面,BeautifulSoup用于html页面的解析
from bs4 import BeautifulSoup
import requests
import time

url = "http://bj.58.com/pbdn/0/"
header = {
    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36',
    'Cookie':'f=n; ipcity=ly%7C%u9F99%u5CA9; userid360_xml=ECD6EBC44A953F262599ECBF200466C6; time_create=1462540691216; myfeet_tooltip=end; bj58_new_session=1; bj58_init_refer=""; bj58_new_uv=1; bj58_id58s="cj1xSHUxVUZhWnhZNjc3Nw=="; sessionid=72fb3011-18c9-4edb-bab8-6da3336820e3; id58=c5/njVcFC7yd81HAAxYnAg==; 58tj_uuid=ab2a30b9-8b32-43fc-8e6c-52d7cff7254f; new_session=1; new_uv=1; utm_source=; spm=; init_refer=; als=0; br58=index_old; f=n',
    'host':'bj.58.com'
}

'''
get58List
用于抓取58的列表里的基础信息
会剔除推广和转转的链接
测试用#url = "http://bj.58.com/pbdn/0/"
'''
def get58List(url):
    webData = requests.get(url)
    soup = BeautifulSoup(webData.text,'lxml')
    infos = soup.select('table[class="tbimg"]')#每一块的结构类似,先根据其基本结构提取出一块块内容
    count = 0

    #对每一块结构进行处理,以做更细致的处理
    for info in infos:
        if(info.find('td',attrs={'class':'img'})):#判断是否有效,以过滤掉百度推广的数据
            count = count + 1
            img = info.find('td',attrs={'class':'img'}).img.get('lazy_src')
            title = info.find('a',attrs={'class':'t'}).get_text()
            jumpUrl = str(info.find('td',attrs={'class':'img'}).a.get('href')).replace('&amp','')#抓取跳转链接,对地址替换掉58的限制用内容
            qq_attest = info.find('div',attrs={'class':'qq_attest'})
            if(qq_attest==None):#对转转的数据进行识别,只有对58的页面才进行详情页的抓取
                if('x.shtml' in jumpUrl):
                    jumpUrl = jumpUrl.split('?psid')[0]
                    get58Info(jumpUrl)
                    #print(img,title,jumpUrl,qq_attest)

    #提取下一页的地址
    if(soup.find('a',attrs={'class':'next'})):
        if(count == 0):#判断该页是否有数据,如果已经没有数据,则停止返回下一页地址
            print('本页已经无内容')
            return None
        nextUrl = "http://bj.58.com" + str(soup.find('a',attrs={'class':'next'}).get('href')).replace('&amp','')
        print("nextUrl:"+nextUrl)
        return nextUrl

'''
get58Info_Count
获取JS里的count数据,

!!!目前该部分无法使用
'''
def get58Info_Count(url):
    count = "0"
    #http://bj.58.com/pingbandiannao/25461164017856x.shtml
    id = url.rsplit('/')[-1].replace("x.shtml","")#从连接里提取出页面ID
    api = "http://jst1.58.com/counter?infoid={}".format(id)#将页面ID并入API中
    data = requests.get(api)
    count = data.text.split('=')[-1]#从返回的数据中提取出count值
    return count


'''
get58Info
用于抓取58详情页里的相关信息
1、价格、成色、区域的获取比较特殊,没有能够识别的标签,故采用抓取内容后识别对应文字的方法
2、count来源于js里,直接抓取的数据0为无效数据
测试用#url = "http://bj.58.com/pingbandiannao/25461164017856x.shtml"
'''
def get58Info(url):
    webData = requests.get(url)
    soup = BeautifulSoup(webData.text,'lxml')
    time.sleep(1)

    #利用BeautifulSoup从html文件里抓取到对应的数据
    #格式化数据,在格式化数据中直接给数据赋值
    data = {
        "type":soup.find('div',attrs={'class':'breadCrumb f12'}).get_text().replace('\n', '-').replace('\t', '-'),
        "title":soup.find('div',attrs={'class':'col_sub mainTitle'}).h1.get_text(),
        "time":soup.find('li',attrs={'class':'time'}).get_text(),
        "count":soup.find('li',attrs={'class':'count'}).get_text(),
        "price":soup.select('span.price')[0].get_text(),
        "howGood":"None",
        "where":soup.select('.c_25d')[0].get_text().split() if soup.select('.c_25d') else "None"   #安全判断,防止无该数据项出错
    }

    #成色没法直接区分,抓取出数据后通过if进行文字判断进行筛选
    for element in soup.find('ul',attrs={'class':'suUl'}).find_all('li'):
        text = str(element.get_text())
        if('成色' in text):
            data["howGood"] = text.replace(' ', '').replace('\n', '').replace('\t', '')
            break

    data["count"] = str(get58Info_Count(url))
    print(data)


'''
get58ByNum
通过url的组装规则,根据要便利的页面范围,去生成对应的url列表,通过遍历列表调用get58List去实现数据抓取
'''
def get58ByNum(start=0,end=5):
    urls = ["http://bj.58.com/pbdn/0/pn{}/".format(str(i)) for i in range(start,end)]
    for url in urls:
        get58List(url)


'''
get58fromPageToEnd
通过在get58List里加入返回值,会返回下一页的地址,通过while语句不断的访问,直到返回的url无效为止。
'''
def get58fromPageToEnd(start=0):
    url = "http://bj.58.com/pbdn/0/pn{}/".format(str(start))
    while url:
        url = get58List(url)
        time.sleep(3)



#入口
__Mode__ = ''#'PageNumber2PageNumber' # 'PageNumber2END'

if __name__ == '__main__':
    if __Mode__ == 'PageNumber2PageNumber':
        get58ByNum(0,3)
    elif __Mode__ == 'PageNumber2END':
        get58fromPageToEnd(50)

    #url = "http://bj.58.com/pingbandiannao/25461164017856x.shtml"
    #get58Info(url)

    url = "http://bj.58.com/pbdn/0/"
    get58List(url)

想法、笔记、总结

1、这个的实现,主要有2块,一块是抓取列表里的信息,把列表里的每个详情页的url抓取出来

1、抓取列表里的信息,把每个列表里的详情页的url抓取出来,交由get58Info去获取详情页里的内容
def get58List(url):
2、将详情页里的详细内容抓取出来,把需要抓取的都抓取出来
 def get58Info(url):

2、里面有些数据比较难以获取,比如说成色,需要获取一类的类似标签后从中便利挑选

其html代码段如下,没办法细分出全部内容:

                        <li>
                            <div class="su_tit">价格:</div>
                            <div class="su_con">
                            <span class="price c_f50">1100</span>元                                                                                                                                     <!-- =S 价格参考 滑过显示层 -->
                                <!--                                    <span id="inPrice" class="in_price" style='display:none'>
                                    <a class="p_link" href="#">价格参考<i class="arw"></i></a>
                                    <div class="in_price_box" id='in_price_box'></div>
                                    </span>
                                -->
                                <!-- =E 价格参考 滑过显示层 -->
                            </div>
                        </li>
                        <li>
                           <div class="su_tit">成色:</div>
                           <div class="su_con">
                            <!-- 成色 -->
                               <span>
                                                                    -
                                                               </span>
                           </div>
                        </li>
                        <!--==E 成色==  -->
                        <li>
                                <div class="su_tit">区域:</div>
                                <div class="su_con">
                                <span class="c_25d">
                        <li>

只能获取出同类的项目进行便利,然后进行判断是否是成色,是的话从中提取出对应的数据

    for element in soup.find('ul',attrs={'class':'suUl'}).find_all('li'):
        text = str(element.get_text())
        if('成色' in text):
            data["howGood"] = text.replace(' ', '').replace('\n', '').replace('\t', '')
            break
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容