Python爬虫之爬取商品信息

需求

  • 爬取若干页上的商品
  • 不包含推广商品和转转商品
  • 获取相应商品的详细信息,例如:标题、发布时间、成色、价格、区域、浏览量等

开发环境

Win7 64bit、Python3.5

代码

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

agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
cookie = 'f=n; f=n; id58=c5/ns1dl9yy83HPfDdvGAg==; ipcity=zz%7C%u90D1%u5DDE%7C0; als=0; __utma=253535702.38279276.1466300209.1466300209.1466300209.1; __utmc=253535702; __utmz=253535702.1466300209.1.1.utmcsr=zz.58.com|utmccn=(referral)|utmcmd=referral|utmcct=/; bj=201661993651; bj58_id58s="WEVVdFlpeD1VM3hkNjQ3MQ=="; sessionid=e2fa9381-317b-4e3f-9e1c-fd3705f6c894; myfeet_tooltip=end; 58home=bj; __track_id=20160619093746385471429630431203178; Hm_lvt_4d4cdf6bc3c5cb0d6306c928369fe42f=1466300268; Hm_lpvt_4d4cdf6bc3c5cb0d6306c928369fe42f=1466300268; city=bj; bdshare_firstime=1466300280136; bangbigtip2=1; f=n; final_history=26224745105338%2C25245379987755%2C26394563690054%2C26399654836521%2C26010296256313; bj58_new_session=0; bj58_init_refer=""; bj58_new_uv=3; 58tj_uuid=1b067d6e-d9f3-4b82-818b-3cdd2263501c; new_session=0; new_uv=3; utm_source=; spm=; init_refer='
referer = 'http://bj.58.com/pbdnipad/0/?PGTID=0d3065d1-0000-114f-c494-6fa3a1961632&ClickID=1'
headers = {'User-Agent':agent,'Cookie':cookie,'Referer':referer}

# 获取页面上除了推广和转转外,所有商品的链接,将链接存储在list中返回。函数有两个参数,end_page参数,
# 表示要获取商品的页数,sale参数默认为0,表示要获取个人商品,若要获取商家商品时,将sale置为1。
def get_links_from_page(end_page,sale=0):
    links= []
    for page in range(1,end_page+1):
        url = 'http://bj.58.com/pbdn/{}/pn{}/'.format(sale,page)
        r = requests.get(url, headers=headers)
        if r.status_code != 200:
            continue
        time.sleep(4)
        soup = BeautifulSoup(r.text, 'lxml')
        for tr in soup.select('#infolist > table.tbimg'):                #避开了推广商品
            for item in tr.find_all('tr', class_=''):                         #避开了转转商品,注意class_的写法
                links.append(item.select('td.t > a.t')[0].get('href'))
    # print(links)
    return links


# 获取某一个商品的浏览量,浏览量是js控制的,直接抓取标签会返回0,在headers中药加入referer
def get_views(url):
    id = url.split('?')[0].split('/')[-1].strip('x.shtml')
    infoid = 'http://jst1.58.com/counter?infoid={}'.format(id)
    r = requests.get(infoid,headers=headers)
    views = r.text.split('=')[-1]
    return views

# 获取商品的信息
def get_info(end_page,sale=0):
    urls = get_links_from_page(end_page,sale=0)
    for url in urls:
        r = requests.get(url, headers = headers)
        if r.status_code != 200:
            continue
        time.sleep(2)
        soup = BeautifulSoup(r.text, 'lxml')
        cate = soup.select('span > a[href="http://bj.58.com/pbdn/"]')
        title = soup.select('div > h1')
        date = soup.select('li.time')
        price = soup.select('span.price')
        state = soup.find_all('div', 'su_con')
        region = soup.select('.c_25d')

        data = {
            'category':cate[0].get_text(),
            'title':title[0].get_text(),
            'date':date[0].get_text(),
            'price':price[0].get_text(),
            'state':list(state[1].stripped_strings)[0],
            'region':''.join(list(region[0].stripped_strings)) if len(region)!=0 else '-',
            'seller':'个人' if sale == 0 else '商家',
            'views': get_views(r.url),   #重定向链接
        }
        print(data)

# 爬取前两页的信息
get_info(2)

运行结果

遇到的问题和解决方案

  1. 获取浏览量时,Chrome一直显示浏览量为0,即使刷新后也没有变化,在Sources中也没有发现任何URL返回浏览量信息。折腾了一个晚上,发现是chrome中的adblock plus没关,关掉后一切正常了。

  2. 使用get_view()函数获取浏览量,最初只把相应的网站传入,结果发有一个商品的浏览量是0,后来发现该链接有重定向链接,使用r.url获取重定向后的链接即可。

  3. 选取网页元素时,使用CSS Selector复制路径即可,但是复制的路径不一定能用,如果出现nth-child(),要改为nth-of-type()。路径中的'>'两边要有空格,否则会报错。

  4. <tbody>标签导致无法正常选取标签
    在最初编程时,为了避免选中推广商品的标签,曾将路径设为#infolist > table.tbimg > tbody > tr > td.t > a.t(这样依然会选中转转商品),结果竟然返回[]。代码如下:

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

url = 'http://bj.58.com/pbdn/0/'
r = requests.get(url)
soup = BeautifulSoup(r.text, 'lxml')
tag = soup.select(#infolist > table.tbimg > tbody > tr > td.t > a.t)
print(tag)

#结果为[]

原因和解决方案:
虽然在Elements下存在tbody标签,但是网页源代码中并没有该标签,如果使用print(soup),发现结果中也没有tbody标签。在网页中,tbody位于table中,用来提高解析速度。将路径改为#infolist > table.tbimg > tr > td.t > a.t即可。

总结

  1. 浏览量是JS控制的,不能通过选取标签的方式获取
  2. 标签的选取需要逐步尝试
  3. 为了避开网站的反爬机制,需要添加headers,设置爬取的时间间隔
  4. 路径的含义
    例如:#infolist > table.tbimg > tbody > tr a.t路径,table.tbimg指class=tbimg的table标签,#infolist指id=infolist的标签,> 代表直接子标签,tr a.t之间的空格代表a是tr的间接子标签。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 任务简述 爬取58同城某页面列表页中,除了转转、推广商品之外的正常商品 要求爬取的商品信息包括:类目标题发帖时间价...
    如恒河沙阅读 673评论 1 1
  • HTML标签解释大全 一、HTML标记 标签:!DOCTYPE 说明:指定了 HTML 文档遵循的文档类型定义(D...
    米塔塔阅读 3,208评论 1 41
  • HTML需要掌握标签 标签(空格分隔): H5+CSS [TOC] 常用标签 img 注意点 和H系列标签/p标签...
    袁俊亮技术博客阅读 2,044评论 1 8
  • 告别 告别 充满了我们生命的 每一时每一刻 我发着牢骚 和沉默告别 我放下碗筷 和饥饿告别 我走出门外 和家庭告别...
    一了0820阅读 397评论 2 6
  • 前几天,带仔仔小朋友去看牙医,他排在第二个,前面是一个六七岁的姐姐,后面是一个六岁的哥哥。 我们进去候诊室的时候,...
    言静思阅读 373评论 0 2