selenium抓取京东数据

最近有抓取商品数据的需求,数据量不多,我们使用selenium来抓取数据,效率不高,但是功能十分强大,并且很难被反爬,对网站也十分友好,不会给对方的服务器造成压力。

*仅供学习交流请勿用于商业用途

首先需要拿到网址,比如我要搜饮料,然后在京东网页上测试
在这里插入图片描述
链接就变成了上面这种形式,然后只提取我们需要的,把多余的字段去掉,测试一下如下网址即可访问到:

https://search.jd.com/Search?keyword=饮料&enc=utf-8

如果我们要搜其他的只用更改饮料这两个字就好了。

然后是我们启动selenium的代码块:

from selenium import webdriver

driver = webdriver.Chrome("./bin/chromedriver")
driver.get("https://search.jd.com/Search?keyword=饮料&enc=utf-8")

webdriver.Chrome()中的参数是chromedriver的路径,windows的环境类似于webdriver.Chrome(“D:/chromedriver_win32/chromedriver.exe”)。
打开网页后我们就需要找到商品的css selector的路径,可以用检查来查看

在这里插入图片描述
然后把selector复制下来
在这里插入图片描述

复制下来是这个样子,但是我们一般不需要这么长,可以剔除中间的一些路径。

#J_goodsList > ul > li:nth-child(1) > div > div.p-name.p-name-type-2

比如我就直接取了第一个和最后一个字段:

from selenium import webdriver

driver = webdriver.Chrome("./bin/chromedriver")
driver.get("https://search.jd.com/Search?keyword=饮料&enc=utf-8")
contents = driver.find_elements_by_css_selector("#J_goodsList .p-name-type-2")
for cont in contents:
    print(cont.text)

先看下打印结果:
在这里插入图片描述
说明定位没问题,我还需要每个条目的链接,在下层a的href字段里:
在这里插入图片描述

driver = webdriver.Chrome("./bin/chromedriver")
driver.get("https://search.jd.com/Search?keyword=饮料&enc=utf-8")
contents = driver.find_elements_by_css_selector("#J_goodsList .p-name-type-2")
for cont in contents:
    _title = cont.text
    _link = cont.find_element_by_css_selector("a").get_attribute('href')
    print(_title)
    print(_link)

下面是打印结果:
在这里插入图片描述
这样再把标题中的换行符去掉,就可以拿到标题与链接的对应关系。

接下来考虑翻页的问题
在这里插入图片描述
同样的套路,将这个按钮的css路径拿到,并且需要考虑最后一页的时候中断翻页(在最后一页的时候会出现disabled字段):

def next_page(driver):
    try:
        check_end = driver.find_element_by_css_selector("#J_topPage > a.fp-next.disabled")
        if check_end.is_enabled():
            return False
    except:
        pass
    try:
        contents = driver.find_element_by_css_selector("#J_topPage > a.fp-next")
        contents.click()
        return True
    except:
        print("no more pages")
        return False

接下来开始愉快的提取商品与链接,但是在第二页就遇到了报错,翻看网页时注意到京东的网页并没有一次性加载完,所以还需要在翻页的时候添加一个将页面拉到最末端的功能,需要借助javascript的命令来实现:

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

这样就把所有的商品和链接列表拿到了,接下来进入每个链接拿商品的参数和价格:
在这里插入图片描述
在这里插入图片描述

from selenium import webdriver

driver = webdriver.Chrome("./bin/chromedriver")
driver.get("https://item.jd.com/5916530.html")

price = driver.find_element_by_css_selector("body span.p-price")

contents = driver.find_elements_by_css_selector("#detail .p-parameter-list")
_parameters = [price.text]
for cont in contents:
    _parameter = cont.text
    if "\n" in _parameter:
        _parameters += _parameter.split("\n")
    else:
        _parameters.append(_parameter)
driver.close()
for _tmp in _parameters:
    print(_tmp)

打印结果:
在这里插入图片描述
接下来就把所有的流程都串起来,看需求可以添加多线程或者协程功能,然后安静模式运行就好了,数据可以写到数据库,或者写到文件里:

#!/usr/local/bin/python3
# -*- coding: UTF-8 -*-

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
import random


def next_page(driver):
    try:
        check_end = driver.find_element_by_css_selector("#J_topPage > a.fp-next.disabled")
        if check_end.is_enabled():
            return False
    except:
        pass
    try:
        contents = driver.find_element_by_css_selector("#J_topPage > a.fp-next")
        contents.click()
        return True
    except:
        print("no more pages")
        return False


def find_item(driver, output_url):
    time.sleep(random.randint(2, 5))
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    contents = driver.find_elements_by_css_selector("#J_goodsList .p-name-type-2")
    for cont in contents:
        _title = cont.text
        _link = cont.find_element_by_css_selector("a").get_attribute('href')
        print(_title)
        print(_link)
        output_url.append([_title.replace("\n", " ").replace("\t", " "), _link])
    while next_page(driver):
        print("start getting next page")
        find_item(driver, output_url)
    return output_url


def run_find(search_word):
    driver = webdriver.Chrome("./bin/chromedriver")
    driver.get("https://search.jd.com/Search?keyword=%s&enc=utf-8" % search_word)
    out_url = find_item(driver, [])
    with open("tmp_url.txt", 'w+') as f:
        f.write("\n".join(["\t".join(x) for x in out_url])+"\n")
    driver.close()


def get_parameters(title, url, outfile):
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    driver = webdriver.Chrome("./bin/chromedriver", options=chrome_options)
    # driver = webdriver.Chrome("./bin/chromedriver")
    driver.get(url)

    price = driver.find_element_by_css_selector("body span.p-price")

    contents = driver.find_elements_by_css_selector("#detail .p-parameter-list")
    _parameters = [price.text]
    for cont in contents:
        _parameter = cont.text
        if "\n" in _parameter:
            _parameters += _parameter.split("\n")
        else:
            _parameters.append(_parameter)
    driver.close()
    with open(outfile, 'a+') as f:
        f.write("\t".join([title, url] + _parameters)+"\n")


if __name__ == '__main__':
    run_find("饮料")
    f_url = open("tmp_url.txt", 'r')
    for idx, l in enumerate(f_url):
        _l = l.rstrip().split("\t")
        print(idx, _l)
        try:
            get_parameters(_l[0], _l[1], "final_item.txt")
        except:
            print("need check: ", _l)
    f_url.close()
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值