【问题标题】:Scraping from Json using beautifulsoup and urllib使用 beautifulsoup 和 urllib 从 Json 中抓取
【发布时间】:2021-06-15 18:06:59
【问题描述】:

我正在使用 json 的示例网站上学习一些抓取。例如,采用以下示例网站:http://www.charitystars.com/product/juve-chelsea-3-0-champions-league-jersey-autographed-by-giorgio-chiellini。源代码在这里view-source:https://www.charitystars.com/product/juve-chelsea-3-0-champions-league-jersey-autographed-by-giorgio-chiellini。我想在第 388-396 行获取信息:

<script>
    var js_data = {"first_time_bid":true,"yourbid":0,"product":{"id":55,"item_number":"P55","type":"PRODUCT","fixed":0,"price":1000,"tot_price":1000,"min_bid_value":1010,"currency":"EUR","raise_bid":10,"stamp_end":"2013-06-14 12:00:00","bids_number":12,"estimated_value":200,"extended_time":0,"url":"https:\/\/www.charitystars.com\/product\/juve-chelsea-3-0-champions-league-jersey-autographed-by-giorgio-chiellini","conversion_value":1,"eid":0,"user_has_bidded":false},"bid":{"id":323,"uid":126,"first_name":"Fabio","last_name":"Gastaldi","company_name":"","is_company":0,"title":"fab1","nationality":"IT","amount":1000,"max_amount":0,"table":"","stamp":1371166006,"real_stamp":"2013-06-14 01:26:46"}};
    var p_currency = '€';
    var conversion_value = '1';
    var merch_items = [];
    var gallery_items = [];

    var inside_gala = false;
</script>

并将每个变量用引号(即“id”、“item_number”、“type”...)保存在同名变量中。

到目前为止,我设法运行以下内容

import requests
from bs4 import BeautifulSoup
from urllib import urlopen
import re
import json
import time
import csv
from bs4 import BeautifulSoup as soup
from pandas import DataFrame

import urllib2
hdr = {"User-Agent": "My Agent"}

req = urllib2.Request(http://www.charitystars.com/product/juve-chelsea-3-0-champions-league-jersey-autographed-by-giorgio-chiellini)
response = urllib2.urlopen(req)

htmlSource = response.read()
soup = BeautifulSoup(htmlSource)

title = soup.find_all("span", {"itemprop": "name"}) # get the title

script_soup = soup.find_all("script")

出于某种原因,script_soup 有很多我不需要的信息。我相信我需要的部分在script_soup[9],但我不知道如何访问它(以有效的方式)。非常感谢您的帮助。

【问题讨论】:

    标签: python urllib scrape


    【解决方案1】:

    数据确实在script_soup[9]。问题是这是一个在脚本标签中硬编码的json 字符串。您可以使用script_soup[9].string 以纯文本形式获取字符串,然后使用split()(如我的示例)或regex 提取json 字符串。然后将字符串加载为带有json.loads() 的python 字典。

    import requests
    from bs4 import BeautifulSoup
    from pandas import DataFrame
    import json
    
    hdr = {"User-Agent": "My Agent"}
    response = requests.get("http://www.charitystars.com/product/juve-chelsea-3-0-champions-league-jersey-autographed-by-giorgio-chiellini", headers=hdr)
    
    soup = BeautifulSoup(response.content)
    script_soup = soup.find_all("script")
    data = json.loads(script_soup[9].string.split('= ')[1].split(';')[0])
    

    数据现在存储在变量data 中。您可以根据需要对其进行解析或将其加载到pandaspd.DataFrame(data)

    【讨论】:

    • 谢谢!我真的很想保存变量“amount”、“bids_number”、“conversion_value”、“currency”、“estimated_value”、“extended_time”、“first_name”、“id”、“last_name”、“max_amount”、“min_bid_value” ", "nationality", "price", "raise_bid", "real_stamp", "stamp_end", "uid" 在不同的向量中。当我创建 dataframedat = pd.DataFrame(data) 时,它给了我一个 4 列的矩阵,我不知道如何使用。我可以像item_number = data.find_all("'item_number'")(或类似)一样简单地创建每个变量,然后将其放入向量中吗?
    • 我尝试了以下但没有成功:import re regex = [] regex = re.compile('"raise_bid":([0-9]*)') raise_bid = regex.findall(data.encode('ascii','ignore').replace("'","")) Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; AttributeError: 'dict' object has no attribute 'encode'我希望创建一个名为raise_bid的变量
    • 我不确定你所说的向量是什么意思。你是说变量吗?您可以这样做:amount = data['bid']['amount']bids_number = data['product']['bids_number'] 等。data 是字典,而不是字符串 - 所以不要使用正则表达式。您可以通过密钥访问这些项目,internet 上有很多关于字典如何工作的信息。
    • 感谢您的解释!这完美!
    【解决方案2】:

    如果你可以使用requestslxml 模块,你可以使用这个

    根据 OP 更新

    import requests
    from lxml import html
    import json
    
    header = {
        'User-Agent': ('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
                       ' Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51'),
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    
    url='http://www.charitystars.com/product/juve-chelsea-3-0-champions-league-jersey-autographed-by-giorgio-chiellini'
    a = requests.get(url,headers=header)
    
    a = html.fromstring(a.text).xpath('//*[@class="page-content"]/script/text()')[0]
    a = a.replace('\n','').replace(' ','')
    b = a.split(';')
    b = [i.split('=') for i in b]
    c = json.loads(b[0][1])
    c['product']
    

    【讨论】:

    • 感谢您的帮助!那么我的问题是如何访问 b[0][1] 中的变量?我想为"product":{ ... } 中的每个变量创建一个变量,以便在我抓取更多列表时将它们存储在一个向量中。
    • c = b[0][1].replace('"product":{','').split(',') & c = [i.split(':') for i in c]
    • 哇!太棒了!我唯一的问题是对于c[11],它给出了[u'"stamp_end"', u'"2013-06-1412', u'00', u'00"'],这是错误的日期,因为c[11][1]返回u'"2013-06-1412',而它应该只是2013-06-14,这样我就可以将12保存为hour 变量。
    猜你喜欢
    • 2018-09-22
    • 2017-11-28
    • 2018-02-07
    • 2016-06-19
    • 2017-08-26
    • 2022-06-13
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多