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

Python爬取当当网评论通常涉及网络爬虫技术,使用如requests库获取网页内容,然后BeautifulSoup、Scrapy等库解析HTML提取评论信息。以下是简要步骤: 1. **安装所需库**:首先需要安装`requests`用于发送HTTP请求,`beautifulsoup4`或`lxml`用于解析HTML。 ```bash pip install requests beautifulsoup4 ``` 2. **发送GET请求**:通过`requests.get()`函数访问当当网商品详情页URL,获取网页源码。 ```python import requests url = "https://product.dangdang.com/XX-XX-XX" # 替换为实际商品链接 response = requests.get(url) ``` 3. **解析HTML**:使用BeautifulSoup解析响应的HTML内容,找到包含评论的区域。 ```python from bs4 import BeautifulSoup soup = BeautifulSoup(response.text, 'html.parser') comments_container = soup.find('div', {'class': 'comment-list'}) # 类名可能会变化,需根据实际情况查找 ``` 4. **提取评论信息**:遍历评论容器内的每个评论元素,提取评论文本、作者、时间等信息。这可能涉及到CSS选择器或XPath表达式。 ```python comments = comments_container.find_all('li') # 或其他标签,视情况而定 for comment in comments: text = comment.find('span', {'class': 'review-text'}).text.strip() author = comment.find('span', {'class': 'author'}).text.strip() timestamp = comment.find('time')['datetime'] print(f"{author} - {timestamp}: {text}") ``` 5. **处理数据存储**:如果想保存评论到文件或数据库,可以考虑使用pandas库或者其他合适的方式。 注意: - 网站可能会有反爬机制,如验证码、IP限制等,所以爬取前应检查并遵守网站的robots.txt规则。 - 长期大量爬取可能会对服务器造成压力,因此建议设置合适的延迟(`time.sleep()`)并尊重网站的爬虫政策。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值