python+requests爬取当当网-商品详情/评论

郑重声明:
本项目的所有代码和相关文章,仅用于经验技术交流分享,禁止将相关技术应用到不正当途径,因为滥用技术产生的风险与本人无关。
文章仅源自个人兴趣爱好,不涉及他用,侵权联系删

目标:爬取当当网指定关键字书籍商品详情信息

最近全民炒股全民基金,调研一下有关基金的数哈哈

第一页:http://search.dangdang.com/?key=%BB%F9%BD%F0&act=input&page_index=1

第二页:http://search.dangdang.com/?key=%BB%F9%BD%F0&act=input&page_index=2

没什么说的,可以翻页爬取

首先看一下列表页的信息,有问题没得

问题不大,想要的书名、作者、价格、评论。都有,以防意外,我们再关注一下源码:

确实都在,可以着手‘拿’数据了。

代码:

def spider():
    headers = {太长,自取}
    url = 'http://search.dangdang.com/?key=%BB%F9%BD%F0&act=input&page_index=1'
    # 避免意外,这里家里有条件的都用一下代理,毕竟爬虫学的好,JY进的早
    # 这里是阿布云服务器
    # 代理服务器
    proxyHost = "http-dyn.abuyun.com"
    proxyPort = "9020"
    # 代理隧道验证信息
    proxyUser = "*****"  # 通行证书
    proxyPass = "*****"  # 通行秘钥
    proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
        "host": proxyHost,
        "port": proxyPort,
        "user": proxyUser,
        "pass": proxyPass,
    }
    proxies = {
        "http": proxyMeta,
        "https": proxyMeta,
    }
    # get请求使用阿布云
    time.sleep(0.1)
    response = requests.get(url=url, proxies=proxies, headers=headers)
    # 个人习惯正则取,也可用lxml的etree方法将html解析成xpath对象
    # 提取商品链接
    res = response.text
    # 提取商品链接
    link_list = re.findall('dd_name="单品图片" href="(.*?)"', res)
    for i, post in enumerate(link_list):
        # 提取商品
        title = re.findall("alt='(.*?)'", res)[i]
        # 作者
        author = re.findall("dd_name='单品作者' title='(.*?)'>", res)[i]
        # 提取商品价格
        price = re.findall('<span class="search_now_price">&yen;(.*?)</span>', res)[i]
        # 提取商品评论
        comment = \
            re.findall('<a href=".*?" target=".*?" name=".*?" dd_name=".*?" class=".*?" ddclick=".*?">(.*?)</a>', res)[
                i]
        print(title)
        print(author)
        print(price)
        print(comment)
        
spider()
          

详情如何在各种场景下使用代理,请参考   https://blog.csdn.net/Owen_goodman/article/details/107353804

到这里,基本都是没什么难度的,我们再继续看一下详情

。。。。已经成功入选白名单。不慌,我们开手机热点,算了,下午继续吧,还有一分钟下班

心态崩了。。

开热点。查看:

 

查看源码:

继续:

有点东西,把链接复制打开看一下

http://product.dangdang.com/index.php?r=callback%2Fdetail&productId=25190224&templateType=publish&describeMap=01000031424%3A1&shopId=0&categoryPath=01.24.02.00.00.00

点击一看,确实是我们需要的商品详情模块,json数据不要紧,我们后期转化一下就ok,先看下链接:

发现json数据链接是由这几个参数productId、template、describeMap、shopId、categoryPath拼接而成,

测试一下

headers = {
    '记得加头'
}
urlss = 'http://product.dangdang.com/index.php?r=callback%2Fdetail&productId=1537211272&templateType=publish&describeMap=1000031416%3A0%2C700003831%3A3&shopId=16447&categoryPath=01.05.07.00.00.00'

response = requests.get(urlss, headers=headers)
str = str(response.json())
json = response.json()
data=json.get('data')
print(data)
print(data['html'])

确实都在,详情的html也在

我们去详情页的源码或者输出的html文件里找一下子。

哦豁,在这

或者直接search都可

我们把js文件复制下来格式化一下:https://www.sojson.com/

就很nice,你要的我都有,我们就可以直接拿参数,来拼上我们的详情页json数据链接,最后再测试一下;

urls = 'http://product.dangdang.com/23641695.html'
response = requests.get(urls, headers=headers)
id = re.findall(r'productId":"(.*?)",', response.text)
path = re.findall(r'categoryPath":"(.*?)",', response.text)
print(id)
print(path)

,就很棒。

最后完整代码:

import csv
import time

from lxml import etree
import requests
import pymysql
from bs4 import BeautifulSoup
from urllib.parse import urlencode
import re
from urllib import parse
from functools import reduce
import datetime


class dandd():

    def spider(self):
        headers = { “记得加头”}
        url = '详情页链接'
        # 这里是阿布云服务器,要用代理,会封IP,而且不进JY
        # 代理服务器
        proxyHost = "http-dyn.abuyun.com"
        proxyPort = "9020"
        # 代理隧道验证信息
        proxyUser = "****"  # 你的通行证书
        proxyPass = "****"  # 你的通行秘钥
        proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
            "host": proxyHost,
            "port": proxyPort,
            "user": proxyUser,
            "pass": proxyPass,
        }
        proxies = {
            "http": proxyMeta,
            "https": proxyMeta,
        }
        # get请求使用阿布云
        time.sleep(0.1)
        response = requests.get(url=url, proxies=proxies, headers=headers)
        # 提取商品链接
        res = response.text
        # 提取商品链接
        link_list = re.findall('dd_name="单品图片" href="(.*?)"', res)
        for i, post in enumerate(link_list):
            # 提取商品
            titles = re.findall("alt='(.*?)'", res)[i]
            if titles:
                title = titles
            else:
                title = ''
            # 作者
            authors = re.findall("dd_name='单品作者' title='(.*?)'>", res)[i]
            if authors:
                author = authors
            else:
                author = ''
            # 提取商品价格
            prices = re.findall('<span class="search_now_price">&yen;(.*?)</span>', res)[i]
            if prices:
                price = prices
            else:
                price = ''
            # 提取商品评论
            comments = \
                re.findall('<a href=".*?" target=".*?" name=".*?" dd_name=".*?" class=".*?" ddclick=".*?">(.*?)</a>',
                           res)[i]
            if comments:
                comment = comments
            else:
                comment = ''

            print(title)
            print(author)
            print(price)
            print(comment)
            # 详情页会封IP哦
            # 代理服务器
            proxyHost = "http-dyn.abuyun.com"
            proxyPort = "9020"
            # 代理隧道验证信息
            proxyUser = "****"  # 通行证书
            proxyPass = "****"  # 通行秘钥
            proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
                "host": proxyHost,
                "port": proxyPort,
                "user": proxyUser,
                "pass": proxyPass,
            }
            proxies = {
                "http": proxyMeta,
                "https": proxyMeta,
            }
            comment_hrefs = str(post)
            time.sleep(0.1)
            comment_html = requests.get(comment_hrefs, headers=headers, proxies=proxies).text

            productId = re.findall(r'productId":"(.*?)"', comment_html)
            template = re.findall(r'template":"(.*?)"', comment_html)
            describeMap = re.findall(r'describeMap":"(.*?)"', comment_html)
            shopId = re.findall(r'shopId":"(.*?)"', comment_html)
            categoryPath = re.findall(r'categoryPath":"(.*?)"', comment_html)

            productId_str = "".join(productId)
            template_str = "".join(template)
            describeMap_str = "".join(describeMap)
            shopId_str = "".join(shopId)
            categoryPath_str = "".join(categoryPath)
            try:
                '''
                # 两种均可
                parm = {
                    'productId': productId_str,
                    'template': template_str,
                    'describeMap': describeMap_str,
                    'shopId': shopId_str,
                    'categoryPath': categoryPath_str,
                }
                url_a1 = 'http://product.dangdang.com/index.php?r=callback%2Fdetail&'
                ajax_url = url_a1 + urlencode(parm)
                aj = ajax_url.strip()
                '''

                aj = 'http://product.dangdang.com/index.php?r=callback%2Fdetail&productId=' \
                     + str(productId_str) \
                     + '&templateType=' \
                     + str(template_str) \
                     + '&describeMap=' \
                     + str(describeMap_str) \
                     + '&shopId=' \
                     + str(shopId_str) \
                     + '&categoryPath=' \
                     + str(categoryPath_str)
                print(aj)
                # 调用ajax请求
                # 这里是阿布云代理
                time.sleep(0.1)
                response = requests.get(aj, headers=headers, proxies=proxies)
                json = response.json()
                data = json.get('data')
                # print(data)
                html = data['html']
                parseHtml = etree.HTML(html)
                TEXT = parseHtml.xpath('//*//text()')
                if TEXT:
                    text = (''.join(
                        [j.replace('\r\n', '').strip() for j in [re.sub(r'(\xa0.*)', '', i) for i in TEXT] if j]))
                else:
                    text = ''
                print(title)
                print(author)
                print(price)
                print(comment)
                with open("当当07-15.csv", 'a+', encoding="utf-8", errors="ignore") as f:
                    f = csv.writer(f)
                    f.writerow(
                        ('商品名:' + str(title), '作者:' + str(author), '商品价格:' + str(price), '商品评论数:' + str(comment),
                         '商品链接:' + str(post), '商品详情:' + str(text)))

            except Exception as e:
                print('详情获取请求出错')
                with open("出错商品.csv", 'a', encoding="utf-8", errors="ignore") as f:
                    f = csv.writer(f)
                    f.writerow((str(title), str(author), str(price), str(comment), str(post), str(e)))
                pass

if __name__ == '__main__':
    d1 = dandd()
    d1.spider()

到这里,商品详情的话,我们就获取完了,如果还想搞点评论的话。。都在这里。过程一样。

OVER.

转载请注明转自:https://blog.csdn.net/Owen_goodman/article/details/107357211

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值