鱼C论坛

 找回密码
 立即注册
查看: 2578|回复: 19

[已解决]京东商品图片爬虫求助

[复制链接]
发表于 2017-4-19 09:09:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
大家好,最近开始学爬虫,买了本电子书学习,里面有段爬取京东商城手机图片的代码,按照里面的代码试了下,却没有下载到图片,但运行时Python却没有报错,想请各路大神看看是什么回事额,感激不尽。

以下是截取电子书的内容,由于电子书排版问题,里面没有缩进的。
11.png
22.png

以下是代码内容:
  1. import re
  2. import urllib.request


  3. def down_jd(url,page):

  4.     html1 = urllib.request.urlopen(url).read()
  5.     html1 = str(html1)
  6.     p1 = '<div id="plist".+? <div class="page clearfix">'
  7.     req1 = re.compile(p1).findall(html1)
  8.     req1 = req1[0]

  9.     p2 = '<img width="220" height="220" data-img="1" data-lazy-img="//(.+?\.jpg)>'
  10.     imgs = re.compile(p2).findall(req1)

  11.     x =1
  12.     for imgsurl in imgs:
  13.         imgsname = 'D:/Python35/myweb/' + str(page) + str(x) + '.jpg'
  14.         imgsurl = 'http://' + imgsurl


  15. for i in range(1,79):
  16. url = 'https://list.jd.com/list.html?cat=9987,653,655&page=' + str(i)
  17. down_jd(url,i)
复制代码
最佳答案
2017-4-19 15:58:10
本帖最后由 gopythoner 于 2017-4-19 16:01 编辑
haski1991 发表于 2017-4-19 15:51
额,谢谢你!看了下的确是少了个双引号,但加上后还是运行木有反应额


你其实已经得到了图片链接,只不过你没有保存图片的过程,你的代码里面根本就没有保存图片的过程,当然就得不到图片啊
你那个电子书里面倒是有保存图片的过程,但是你自己没有写完
不过你可以不用它这种方式
如果你要保存图片,可以在你函数最后面加2句(就是这句imgsurl = 'http://' + imgsurl下面加,跟这句的缩进保存一致就行)
  1. with open(imgsname,"wb") as f:   
  2.   f.write(imgsurl)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-4-19 10:07:42 | 显示全部楼层
图片下载的函数都没有调用,肯定没有动静啊
用urlretrieve试一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 11:29:15 | 显示全部楼层
本帖最后由 ooxx7788 于 2017-4-19 11:34 编辑

我都没看见保存图片的语句啊。
而且现在京东的网页代码已经变了,照抄是爬不了的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 12:59:00 | 显示全部楼层
我比较好奇的是,这个电子书里面的代码居然都没有缩进?
Python的缩进应该是最重要的语法规则吧,我看你这个截图怎么全部没缩进啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 13:46:15 | 显示全部楼层
本帖最后由 zlj19931010 于 2017-4-19 14:28 编辑

可以拿到数据,但是我去这个网页看了下,他一开始就只有加载前十<li class="gl-item">,后面的都是延时通过js加载的,所以只能爬到前十张图片

不对,有的,看来是正则的问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-19 14:57:41 | 显示全部楼层
gopythoner 发表于 2017-4-19 12:59
我比较好奇的是,这个电子书里面的代码居然都没有缩进?
Python的缩进应该是最重要的语法规则吧,我看你这 ...

是的,我也纳闷呢,看了下说是因为京东阅读是根据自己的换行规则来排版的,所以只有纸质版的书才有缩进- -
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-19 14:59:29 | 显示全部楼层
zlj19931010 发表于 2017-4-19 13:46
可以拿到数据,但是我去这个网页看了下,他一开始就只有加载前十,后面的都是延时通过js加载的,所以只能爬 ...

为什么我一张也爬不到下来额- -
运行又木有报错- -求大神指点下额
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 15:31:47 | 显示全部楼层
本帖最后由 gopythoner 于 2017-4-19 15:32 编辑

这里,换成我这个就可以了
  1. p2 = '<img width="220" height="220" data-img="1" data-lazy-img="//(.+?\.jpg)">'
复制代码


我只改了一点点,就是在你的基础上加了个双引号,最后.jpg)后面加了一个"
你可以试试,应该可以匹配到你要的链接了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 15:46:56 | 显示全部楼层
gopythoner 发表于 2017-4-19 15:31
这里,换成我这个就可以了

我给你改了正则之后发现你那个电子书里面其实是有这个双引号的,只是你自己写的时候弄掉了,所以匹配不到链接
这说明了一个问题,就是,这个正则应该是你自己手打出来的
我建议你不要手打,这样很容易弄错,比如像你这次,就掉了一个双引号
正确的的做法(我个人认为)应该是这样:
1,先复制几个(到底是几个你可以自己去观察)图片链接所在标签,如下
  1. <img width="220" height="220" data-img="1" data-lazy-img="//img10.360buyimg.com/n7/jfs/t3724/347/1016217917/255875/c5380734/581ae701N723b098d.jpg">
复制代码
  1. <img width="220" height="220" data-img="1" data-lazy-img="//img13.360buyimg.com/n7/jfs/t3985/297/2449532246/71079/4a6ed5d9/58aa3f38N287b21ec.jpg">
复制代码

2,然后观察标签的规律,从上2个可以看出(建议你多看几个),标签前面都不变,只有图片链接部分变了
3,既然只有图片链接变了,就整个复制一个标签,然后把链接部分删掉换成正则(.+?\.jpg),这样,你就直接得到了一个正则表达式了
这种方式有2个好处,第一就是比较省事,因为不需要自己去打出来,第二就是不容易出错,因为是复制的,所以不会出现你这种打掉一些字符的问题
个人见解,仅供参考

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-19 15:51:04 | 显示全部楼层
gopythoner 发表于 2017-4-19 15:31
这里,换成我这个就可以了

额,谢谢你!看了下的确是少了个双引号,但加上后还是运行木有反应额
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 15:58:10 | 显示全部楼层    本楼为最佳答案   
本帖最后由 gopythoner 于 2017-4-19 16:01 编辑
haski1991 发表于 2017-4-19 15:51
额,谢谢你!看了下的确是少了个双引号,但加上后还是运行木有反应额


你其实已经得到了图片链接,只不过你没有保存图片的过程,你的代码里面根本就没有保存图片的过程,当然就得不到图片啊
你那个电子书里面倒是有保存图片的过程,但是你自己没有写完
不过你可以不用它这种方式
如果你要保存图片,可以在你函数最后面加2句(就是这句imgsurl = 'http://' + imgsurl下面加,跟这句的缩进保存一致就行)
  1. with open(imgsname,"wb") as f:   
  2.   f.write(imgsurl)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-19 16:19:44 | 显示全部楼层
gopythoner 发表于 2017-4-19 15:58
你其实已经得到了图片链接,只不过你没有保存图片的过程,你的代码里面根本就没有保存图片的过程,当然 ...

谢谢大神!终于能下了,大神能加个QQ好友不
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 16:27:08 | 显示全部楼层
本帖最后由 zlj19931010 于 2017-4-19 16:29 编辑

我发现1-10页和10-~页返回的数据不一样
然后1-10也返回的数据我要用红色代码处理 为什么用这个<div id="plist".+?<div class="page clearfix">正则取出来的数据是空
import re
import os
import urllib.request


def fetchData(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent',
                   'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36')
    response = urllib.request.urlopen(req)
    return response


def getImageUrl(pageUrl):
    images = []

    response = fetchData(pageUrl)
    html = response.read().decode("utf-8")

    p1 = '<div id="plist".+?<div class="page clearfix">'
    req1 = re.compile(p1).findall(html)
    if len(req1) < 1:
        # 这边很奇怪,明明有<div id="plist"和<div class="page clearfix">就是不能匹配,只能这样曲线救国了
        req1 = html.split('<div id="plist"')[1]
        req1 = req1.split('<div class="page clearfix">')[0]

    else:
        req1 = req1[0]

    p2 = '<img width="220" height="220" data-img="1".+?\.jpg'
    imgs = re.compile(p2).findall(req1)
    for each in imgs:
        # 打印出//之后的数据
        images.append(each.split('//')[1])
    return images


def down_jd(url,save_path):
    imageUrls = getImageUrl(url)
    # 指定文件夹不存在就创建文件夹
    if not os.path.exists(save_path):
        os.makedirs(save_path)

    os.chdir(save_path)
    i = 0
    for each in imageUrls:
        each = "http://%s" % each
        image_one = fetchData(each).read()
        image_name = 'jd_phone_%d.jpg' % i
        i += 1;
        with open(image_name, 'wb') as f:
            f.write(image_one)


for i in range(1,5):
    url = 'https://list.jd.com/list.html?cat=9987,653,655&page=' + str(i)
    down_jd(url, "d://zlj//jd_phone//page%d" % i)

  1. import re
  2. import os
  3. import urllib.request


  4. def fetchData(url):
  5.     req = urllib.request.Request(url)
  6.     req.add_header('User-Agent',
  7.                    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36')
  8.     response = urllib.request.urlopen(req)
  9.     return response


  10. def getImageUrl(pageUrl):
  11.     images = []

  12.     response = fetchData(pageUrl)
  13.     html = response.read().decode("utf-8")

  14.     p1 = '<div id="plist".+?<div class="page clearfix">'
  15.     req1 = re.compile(p1).findall(html)
  16.     if len(req1) < 1:
  17.         # 这边很奇怪,明明有<div id="plist"和<div class="page clearfix">就是不能匹配,只能这样曲线救国了
  18.         req1 = html.split('<div id="plist"')[1]
  19.         req1 = req1.split('<div class="page clearfix">')[0]
  20.     else:
  21.         req1 = req1[0]

  22.     p2 = '<img width="220" height="220" data-img="1".+?\.jpg'
  23.     imgs = re.compile(p2).findall(req1)
  24.     for each in imgs:
  25.         # 打印出//之后的数据
  26.         images.append(each.split('//')[1])
  27.     return images


  28. def down_jd(url,save_path):
  29.     imageUrls = getImageUrl(url)
  30.     # 指定文件夹不存在就创建文件夹
  31.     if not os.path.exists(save_path):
  32.         os.makedirs(save_path)

  33.     os.chdir(save_path)
  34.     i = 0
  35.     for each in imageUrls:
  36.         each = "http://%s" % each
  37.         image_one = fetchData(each).read()
  38.         image_name = 'jd_phone_%d.jpg' % i
  39.         i += 1;
  40.         with open(image_name, 'wb') as f:
  41.             f.write(image_one)


  42. for i in range(1,5):
  43.     url = 'https://list.jd.com/list.html?cat=9987,653,655&page=' + str(i)
  44.     down_jd(url, "d://zlj//jd_phone//page%d" % i)




复制代码




想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 16:37:52 | 显示全部楼层
haski1991 发表于 2017-4-19 16:19
谢谢大神!终于能下了,大神能加个QQ好友不


大神这个称呼放我身上真的不合适,我是业余的,也是新手,只不过我可能爬虫写的比你多那么一点点所以对爬虫的一些基层比你好一些罢了
至于加QQ,也没啥用,现在谁还用QQ啊
有问题直接放论坛提问就行了
发现问题和解决问题的过程就是提升能力的过程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-4-19 16:42:37 | 显示全部楼层
zlj19931010 发表于 2017-4-19 16:27
我发现1-10页和10-~页返回的数据不一样
然后1-10也返回的数据我要用红色代码处理 为什么用这个

额- -又捕获一个大神
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-19 16:49:47 | 显示全部楼层
zlj19931010 发表于 2017-4-19 16:27
我发现1-10页和10-~页返回的数据不一样
然后1-10也返回的数据我要用红色代码处理 为什么用这个

虽然我没仔细去研究这个网页的信息标签
但是我只能说,很多时候正则表达式提取信息的方式有点太规则了,这要求网页的信息必须按照正则的来,但是实际上有的网页信息可能并不那么规则
所以,我几乎不用正则提取网页信息,一般都是用的BeautifulSoup4,按照标签去提取信息,毕竟网页的标签也是开发网页的人需要维护的,所以他们不会去乱写标签的,所以标签一般都比较规范
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-19 18:14:39 | 显示全部楼层
gopythoner 发表于 2017-4-19 16:37
大神这个称呼放我身上真的不合适,我是业余的,也是新手,只不过我可能爬虫写的比你多那么一 ...

感谢你的帮助!希望以后我再遇到问题的时候能为我指点迷津
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-20 01:03:42 | 显示全部楼层
本帖最后由 zlj19931010 于 2017-4-20 01:11 编辑
gopythoner 发表于 2017-4-19 16:49
虽然我没仔细去研究这个网页的信息标签
但是我只能说,很多时候正则表达式提取信息的方式有点太规则了, ...

  1. html = response.read().decode("utf-8")
复制代码

把这个改成
  1. html = str(response.read())
复制代码

不用decode('utf-8')正则就能匹配了

然后去比较了两种方式产生的html代码:
decode出来的内容是这个样子
  1. </div>
  2.                                                <div id="plist" class="goods-list-v2 J-goods-list gl-type-3 "> 省略中间的内容</div>
  3.                                                             <div class="page clearfix">
复制代码


没有decode,直接str出来的内容是这个样子:
  1. </div><div id="plist" class="goods-list-v2 J-goods-list gl-type-3 "省略中间内容</div></div><div class="page clearfix">
复制代码


匹配的正则代码
  1. p1 = '<div id="plist".+?<div class="page clearfix">'
复制代码

这不是只要头是<div id="plist"开头,尾是<div class="page clearfix">结尾的字符串都能匹配嘛



但是decode之后的字符串即使包含了 头是<div id="plist"开头,尾是<div class="page clearfix">结尾的字符串  也还是不能通过正则匹配
而直接str处理的,就能匹配,就很难受。。。不知道为什么会这样!!
help,要睡不着觉了骂的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-20 09:07:14 | 显示全部楼层
第一种里面有换行,也就是信息里面有换行符“\n”,其实有的还有“\t”
而正则里面的(.+?)是不包含换行符的,所以,这个括号里面的是没有考虑换行符的问题的,如果要匹配第一张,需要修改这个括号里面的正则,具体怎么改我倒是不记得
PS:(我很少用正则,对这个不熟,之所以知道有换行符的正则需要特殊处理是之前遇到过这种情况,而我的做法是在进行匹配之前使用replace()方法,把需要匹配的字符串中的换行符和空格,还有"\t"这种都替换掉,然后再匹配)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-20 12:06:44 | 显示全部楼层
gopythoner 发表于 2017-4-20 09:07
第一种里面有换行,也就是信息里面有换行符“\n”,其实有的还有“\t”
而正则里面的(.+?)是不包含换行符的 ...

匹配除换行符 \n 之外的任何单字符
尼玛,我明明昨天还特地去百度了 . 能匹配什么,
尼玛眼瞎了,看了还是觉着 . 能匹配所有。

正所谓当局者迷啊

谢过
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 03:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表