Python 如何使用beautiful soup从shopee中获取数据

Python 如何使用beautiful soup从shopee中获取数据,python,web-scraping,beautifulsoup,Python,Web Scraping,Beautifulsoup,我目前是一名学生,在那里我学习了beautifulsoup,因此我的讲师和我一样,可以从shopee中获取数据,但我无法获取产品的详细信息。目前,我正试图从中提取数据。我只想知道产品的名称和价格。有人能告诉我为什么我不能使用beautifulsoup刮取数据吗 这是我的密码: from requests import get from bs4 import BeautifulSoup url = "https://shopee.com.my/shop/13377506/search?page=

我目前是一名学生,在那里我学习了beautifulsoup,因此我的讲师和我一样,可以从shopee中获取数据,但我无法获取产品的详细信息。目前,我正试图从中提取数据。我只想知道产品的名称和价格。有人能告诉我为什么我不能使用beautifulsoup刮取数据吗

这是我的密码:

from requests import get
from bs4 import BeautifulSoup

url = "https://shopee.com.my/shop/13377506/search?page=0&sortBy=sales"
response= get (url)
soup=BeautifulSoup(response.text,'html.parser')
print (soup)

请发布您的代码,以便我们提供帮助

或者你可以这样开始:)

从bs4导入BeautifulSoup作为汤
从urllib.request导入urlopen作为uReg
我的url=“”
uClient=uReg(我的url)
page_html=uClient.read()

这个问题(对于python初学者)有点棘手,因为它涉及selenium(用于无头浏览)和beautifulsoup(用于html数据提取)的组合。此外,由于文档对象模型(DOM)被封装在javascripting中,因此问题变得很困难。我们知道有javascript,因为当我们只使用beautifulsoup访问网站时,会收到一个空的响应,比如,汤中的项目的

打印(项目获取文本())

因此,要从这样一个有脚本语言控制其DOM的网页中提取数据,我们必须使用selenium进行无头浏览(这告诉网站浏览器正在访问它)。我们还必须使用某种延迟参数(它告诉网站它是由人访问的)。为此,selenium库中的函数
WebdriverWait()
将有所帮助

现在,我将介绍解释该过程的代码片段

首先,导入必要的库

from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from time import sleep
接下来,初始化无头浏览器的设置。我用的是chrome

# create object for chrome options
chrome_options = Options()
base_url = 'https://shopee.com.my/shop/13377506/search?page=0&sortBy=sales'

# set chrome driver options to disable any popup's from the website
# to find local path for chrome profile, open chrome browser
# and in the address bar type, "chrome://version"
chrome_options.add_argument('disable-notifications')
chrome_options.add_argument('--disable-infobars')
chrome_options.add_argument('start-maximized')
chrome_options.add_argument('user-data-dir=C:\\Users\\username\\AppData\\Local\\Google\\Chrome\\User Data\\Default')
# To disable the message, "Chrome is being controlled by automated test software"
chrome_options.add_argument("disable-infobars")
# Pass the argument 1 to allow and 2 to block
chrome_options.add_experimental_option("prefs", { 
    "profile.default_content_setting_values.notifications": 2
    })
# invoke the webdriver
browser = webdriver.Chrome(executable_path = r'C:/Users/username/Documents/playground_python/chromedriver.exe',
                          options = chrome_options)
browser.get(base_url)
delay = 5 #secods
接下来,我声明空列表变量来保存数据

# declare empty lists
item_cost, item_init_cost, item_loc = [],[],[]
item_name, items_sold, discount_percent = [], [], []
while True:
    try:
        WebDriverWait(browser, delay)
        print ("Page is ready")
        sleep(5)
        html = browser.execute_script("return document.getElementsByTagName('html')[0].innerHTML")
        #print(html)
        soup = BeautifulSoup(html, "html.parser")

        # find_all() returns an array of elements. 
        # We have to go through all of them and select that one you are need. And than call get_text()
        for item_n in soup.find_all('div', class_='_1NoI8_ _16BAGk'):
            print(item_n.get_text())
            item_name.append(item_n.text)

        # find the price of items
        for item_c in soup.find_all('span', class_='_341bF0'):
            print(item_c.get_text())
            item_cost.append(item_c.text)

        # find initial item cost
        for item_ic in soup.find_all('div', class_ = '_1w9jLI QbH7Ig U90Nhh'):
            print(item_ic.get_text())
            item_init_cost.append(item_ic.text)
        # find total number of items sold/month
        for items_s in soup.find_all('div',class_ = '_18SLBt'):
            print(items_s.get_text())
            items_sold.append(item_ic.text)

        # find item discount percent
        for dp in soup.find_all('span', class_ = 'percent'):
            print(dp.get_text())
            discount_percent.append(dp.text)
        # find item location
        for il in soup.find_all('div', class_ = '_3amru2'):
            print(il.get_text())
            item_loc.append(il.text)

        break # it will break from the loop once the specific element will be present. 
    except TimeoutException:
        print ("Loading took too much time!-Try again")
此后,我使用
zip
函数组合不同的列表项

rows = zip(item_name, item_init_cost,discount_percent,item_cost,items_sold,item_loc)
最后,我将这些数据写入光盘

import csv
newFilePath = 'shopee_item_list.csv'
with open(newFilePath, "w") as f:
    writer = csv.writer(f)
    for row in rows:
        writer.writerow(row)
作为一种良好的做法,在任务完成后关闭无头浏览器是明智的。所以我把它编码为

# close the automated browser
browser.close()
结果

Nestle MILO Activ-Go Chocolate Malt Powder (2kg)
NESCAFE GOLD Refill (170g)
Nestle MILO Activ-Go Chocolate Malt Powder (1kg)
MAGGI Hot Cup - Asam Asam Laksa (60g)
MAGGI 2-Minit Curry (79g x 5 Packs x 2)
MAGGI PAZZTA Cheese Macaroni 70g
.......
29.90
21.90
16.48
1.69
8.50
3.15
5.90
.......
RM40.70
RM26.76
RM21.40
RM1.80
RM9.62
........
9k sold/month
2.3k sold/month
1.8k sold/month
1.7k sold/month
.................
27%
18%
23%
6%
.............
Selangor
Selangor
Selangor
Selangor
读者须知

OP让我注意到xpath并没有像我在回答中给出的那样工作。两天后我再次查看了网站,发现了一个奇怪的现象。
div
类的
class
属性确实发生了变化。我找到了一个新的。但这并没有多大帮助。所以现在,我认为shoppee网站中的div属性可以再次更改。我把这个问题留给以后解决

操作说明

安娜,上述代码仅适用于一页,即仅适用于网页,
https://shopee.com.my/shop/13377506/search?page=0&sortBy=sales
。我邀请您通过解决如何在销售标签下为多个网页刮取数据来进一步提高您的技能。您的提示是本页面右上角的
1/9
和/或页面底部的
12345
链接。另一个提示是查看urlparse库中的urljoin。希望这能让你开始

有用的资源


页面在第一个请求通过ajax async发送到页面后加载,因此发送一个请求并获取所需页面的源代码似乎是不可能的

你应该模拟一个浏览器,然后你可以得到源代码,你可以使用beautifulsoup。参见代码:

美苏路
从selenium导入webdriver
从selenium.webdriver.common.by导入
从selenium.webdriver.support.ui导入WebDriverWait
从selenium.webdriver.support将预期的_条件导入为EC
从bs4导入BeautifulSoup
驱动程序。获取(“https://shopee.com.my/shop/13377506/search?page=0&sortBy=sales")
WebDriverWait(驱动程序,30)。直到(EC.presence_of_element_located((By.CSS_SELECTOR,“.shop search result view”))
html=driver.page\u源
soup=BeautifulSoup(html,'html.parser')
搜索=汤。选择一个(“.商店搜索结果视图”)
产品=搜索。全部查找('a')
对于产品中的p:
name=p.select('div[data sqe=“name”]>div')[0]。获取文本()
price=p.select('div>div:nth child(2)>div:nth child(2)')[0]。获取文本()
product=p.select('div>div:n个孩子(2)>div:n个孩子(4)')[0]。获取文本()
打印('名称:'+名称)
打印('价格:'+价格)
打印('product:'+product+'\n')
然而,使用selenium是获得所需一切的好方法。请参见下面的示例:

硒法
从selenium导入webdriver
从selenium.webdriver.common.by导入
从selenium.webdriver.support.ui导入WebDriverWait
从selenium.webdriver.support将预期的_条件导入为EC
驱动程序。获取(“https://shopee.com.my/shop/13377506/search?page=0&sortBy=sales")
WebDriverWait(驱动程序,30)。直到(EC.presence_of_element_located((By.CSS_SELECTOR,“.shop search result view”))
search=driver.find_element_by_css_选择器(“.shop search result view”)
产品=搜索。通过css选择器(“a”)查找元素
对于产品中的p:
name=p.find_element_by_css_选择器('div[data sqe=“name”]>div')。text
price=p.find_element_by_css_选择器('div>div:nth child(2)>div:nth child(2)')。文本
product=p.通过css选择器查找元素('div>div:nth child(2)>div:nth child(4)')。文本
打印('名称:'+名称)
打印('price:'+price.replace('\n','|'))
打印('product:'+product+'\n')

添加您迄今为止尝试过的代码片段,否则有人会如何帮助您您好,欢迎使用so。请添加您迄今为止尝试过的输入和预期输出。我为我的无知感到抱歉@RajuBhaya@Ana您可以检查我的答案,mnm也正确地声明了Dom元素。我添加了selenium和beautifulsoup。不要发布不完整的答案。我理解你试图帮助OP,但你发布的内容实际上没有多大帮助。理想情况下,您应该以评论的形式提供此帮助!明白我的意思吗?比
Nestle MILO Activ-Go Chocolate Malt Powder (2kg)
NESCAFE GOLD Refill (170g)
Nestle MILO Activ-Go Chocolate Malt Powder (1kg)
MAGGI Hot Cup - Asam Asam Laksa (60g)
MAGGI 2-Minit Curry (79g x 5 Packs x 2)
MAGGI PAZZTA Cheese Macaroni 70g
.......
29.90
21.90
16.48
1.69
8.50
3.15
5.90
.......
RM40.70
RM26.76
RM21.40
RM1.80
RM9.62
........
9k sold/month
2.3k sold/month
1.8k sold/month
1.7k sold/month
.................
27%
18%
23%
6%
.............
Selangor
Selangor
Selangor
Selangor