web-crawling - get item-title from bandcamp.com - xpath

I try to get the item-title from new releases at bandcamp.com from the 'Discover' part of the page (rock->all rock->new arrivals)
scrapy shell 'https://bandcamp.com/?g=rock&s=new&p=0&gn=0&f=all&w=0'
Part of the relevant source code of the page looks like this:
<div class="col col-3-12 discover-item">
<a data-bind="click: playMe, css: { 'playing': playing }" class="item-link playable">
<span class="item-img ratio-1-1">
<img class="art" data-bind="src_art: { 'art_id': artId, 'format': 'art_tags_large' }" src="https://f4.bcbits.com/img/a1631562669_9.jpg">
<span class="plb-btn">
<span class="plb-bg"></span>
<span class="plb-ic"></span>
</span>
</span>
</a><a data-bind="attr: { 'href': itemURL }, text: title, click: playMe" class="item-title" href="https://reddieseloff.bandcamp.com/album/dead-rebel?from=discover-new">Dead Rebel</a>
<a data-bind="attr: { 'href': bandURL }, text: artist, click: playMe" class="item-artist" href="https://reddieseloff.bandcamp.com?from=discover-new">Red Diesel</a>
<span class="item-genre" data-bind="text: genre">rock</span>
</div>
I tried to get the text of item-title (in this example 'Dead Rebel') with the help of xpath:
response.xpath('//div[#class="col col-3-12 discover-item"]//a[#class="item-title"]/text()').extract()
but it returns nothing.
[]
It's also not working for 'item-artist' so i wonder what i'm doing wrong.
I appreciate any help.

All of the data you seek is hidden in the a hidden div node inside of the page body.
When your browser loads the webpage, javascript instructs how to unpack and display this data and since scrapy does not run any javscript you need to do this step yourself:
# all of the data is under "<div id="pagedata" data-blob=" attribute
data = response.css('div#pagedata::attr(data-blob)').extract()
import json
data = json.loads(data[0])
# dig through this python dictionary to find your data
(it has pretty much everything, even more than the page displays)

Related

How to perform concatenation in <img> tag in the context of VueJS

I am trying to perform concatenation in img tag and here below is what i am trying to do:
<div class="vx-row">
<div v-for="item in items" class="vx-col" v-bind:key="item.id">
<div class="w-full mb-base">
<vx-card>
...
<img :src="require('./img/stars_' + item.id + '_logo.png')" alt=""/>
...
</vx-card>
</div>
</div>
</div>
I am trying to concatenate the item.id to the image path as i am making my code dynamic such that when the cards are displayed then the respective image is displayed.
Please let me know how it can be done, initially i could see images in respective cards but then i tried using
<img :src="require(`./img/stars_${this.$route.params.item_id}_logo.png`)">
in other components then i get error every where.
Here is the error that i get everywhere:
Here you can try a shorthand that webpack will use.
HTML:
<img :src="getByPath(item.id)" v-bind:alt="item.id">
Method:
getByPath(id) {
return require('./img/stars_' + id + '_logo.png')
}
you can do with method like below code
try this:
<div class="vx-row">
<div v-for="item in items" class="vx-col" v-bind:key="item.id">
<div class="w-full mb-base">
<vx-card>
...
<img :src="getImgUrl(item.id)" alt=""/>
...
</vx-card>
</div>
</div>
</div>
and create method:
getImgUrl(value) {
return `./img/stars_${value}_logo.png`
},

Parsing through response created with XPath

Using Scrapy, I want to extract some data from a HTML well-formed site. With XPath I am able to extract a list of items, but I am not able to extra data from the elements in the list, using XPath
All XPath's have been tested using XPather. I have tested the issue using a local file that contains the webpage, same issue.
Here goes:
# Get the webpage
fetch("https://www.someurl.com")
# The following gives me the expected items from the HTML
products = response.xpath("//*[#id='product-list-146620']/div/div")
The items are like this:
<div data-pageindex="1" data-guid="13157582" class="col ">
<div class="item item-card item-card--static">
<div class="item-card__inner">
<div class="item__image item__image--overlay">
<a href="/www.something.anywhere?ref_gr=9801" class="ratio_custom" style="padding-bottom:100%">
</a>
</div>
<div class="item__text-container">
<div class="item__name">
<a class="item__name-link" href="/c.aspx?ref_gr=9801">The text I want</a>
</div>
</div>
</div>
</div>
</div>
When using the following Xpath to extract "The text I want", i dont get anything:
XPATH_PRODUCT_NAME = "/div/div/div/div/div[contains(#class,'item__name')]/a/text()"
products[0].xpath(XPATH_PRODUCT_NAME).extract()
The output is empty, why?
Try the following code.
XPATH_PRODUCT_NAME = ".//div[#class='item__name']/a[#class='item__name-link']/text()"
products[0].xpath(XPATH_PRODUCT_NAME).extract()

Back to Top Link, Dynamically Created, with Scroll

SUMMARY:
I need to insert a "Back to Top" links after every <div class="wrapSection">. I've been successful using the following:
<script>
$('.wrapSection').after('
<div class="backToTop clearfix">
Back To Top
</div>
');
</script>
However, I want to use a smooth scroll when clicking 'Back to Top.' With that in mind, I tried the following:
<script>
$('.wrapSection').after('
<div class="backToTop clearfix">
<a href="javascript:void(0)" onclick="goToByScroll('top')" class="up">
Back To Top
</a>
</div>
');
</script>
That does not work. Being a jQuery rookie, I did what seemed logical, which seems to never be the correct answer.
IN A NUTSHELL
More or less, I need this to appear, dynamically, after every <div class="wrapSection">:
<div class="backToTop">
<a class="top" href="javascript:void(0)" onclick="goToByScroll('top')">
Back to Top
</a>
</div>
This is the solution I came up with:
​$(document).ready(function() {
// Markup to add each time - just give the element a class to attach an event to
var top_html = '<div class="backToTop">Back To Top</div>';
$(".wrapSection").after(top_html);
// Use event delegation (see http://api.jquery.com/on/)
$("body").on("click", ".top", function(e) {
e.preventDefault();
$("html,body").animate({ scrollTop: 0 }, "slow");
});
});​
You can try a jsFiddle here: http://jsfiddle.net/F9pDw/

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?
I don't get the expected results when using the following:
HTML
<div id="itemsView"
data-role="view"
data-model="vm">
<ul data-role="listview" data-bind="source: items"
data-template="itemsTemplate">
</ul>
<script id="itemsTemplate" type="text/x-kendo-template">
<li>
#=Name#
</li>
</script>
<input type="text" data-bind="value: newValue" />
<button data-role="button" data-bind="click: update">update</button>
</div>​
JavaScript
var vm = kendo.observable({
items: [{
Name: "Item1"}],
newValue: '',
update: function(e) {
var item = this.get("items")[0];
item.set("Name", this.get("newValue"));
//adding the follwoing line makes it work as expected
kendo.bind($('#itemsView'), vm);
}
});
kendoApp = new kendo.mobile.Application(document.body, {
transition: "slide"});​
I expect the listview to reflect the change to the Name property of that item. Instead, a new item is added to the listview. Examining the array reveals that there is no additional item, and that the change was made. (re)Binding the view to the view-model updates the list to reflect the change. Re-Binding after a change like this doesn't seem to make any sense.
Here is the jsfiddle:
http://jsfiddle.net/5aCYp/2/
Not sure if I understand your question properly: but this is how I did something similar with Kendo Web UI, I expect mobile is not so different from Web UI from API perspective.
$element.kendoListView({
dataSource: list,
template: idt,
editTemplate: iet,
autoBind: true
});
The way I bind the listview is different, but I guess you can get similar results with your method as well.
I pass two templates to the list view, one for displaying and one for editing.
Display template contains a button (or any element) with css class k-edit to which kendo will automatically bind the listview edit action.
display template:
<div class="item">
# if (city) { #
#: city #<br />
# } #
# if (postCode) { #
#: postCode #<br />
# } #
<div class="btn">
<span class="k-icon k-edit"></span>Edit
<span class="k-icon k-delete"></span>Delete
</div>
</div>
Edit template
<div class="item editable">
<div>City</div>
<div>
<input type="text" data-bind="value: city" name="city" required="required" validationmessage="*" />
<span data-for="city" class="k-invalid-msg"></span>
</div>
<div>Post Code</div>
<div>
<input type="text" data-bind="value: postCode" name="postCode" required="required" validationmessage="*" />
<span data-for="postCode" class="k-invalid-msg"></span>
</div>
<div class="btn">
<span class="k-icon k-update"></span>Save
<span class="k-icon k-cancel"></span>Cancel
</div>
</div>
Clicking that element will put the current element on edit mode using the editTemplate.
Then on the editTemplate there is another button with k-update class, again to which kendo will automatically bind and call the save method on the data source.
Hopefully this will give you more ideas on how to solve your issue.
The problem was caused by the <li> in the template. The widget already supplies the <li> so the additional <li> messes up the rendering. This question was answered by Petyo in the kendo ui forums

How to stop auto-refresh onclick from thumbnails?

I have an image gallery on my site that uses thumbnails that enlarge above the thumbnail line when clicked on. I'm having an issue with the auto-refresh; every time I click one of the thumbnails, the page refreshes, which restores it to the "master image".
I'm not (and sort of refuse, on the grounds that I believe all this can be done with simple CSS and HTML) using anything fancy to write this code, despite my knowledge of HTML being amateur at best.
Here's a sample of the code. Let me know if you need to see a different piece of it.
<div id="rightcol">
<img name="ImageOnly. src='#' /><img src="#" />
</div>
<div id="leftcol"> <div>
<a href="" onclick="ImageOnly.src='#'"><img src="#" />
</div>
Edit: Somehow I seem to have fixed this issue by changing
<a href="" onclick="ImageOnly.src='#'">
to
<a href="#" onclick="ImageOnly.src='#'">
Not really sure why this worked but would love an explanation...?
Why not just use some simple ajax/javascript .innerHTML? instead of trying to stop the auto refresh that occurs when you click on a hyperlink that has #. That way you could update the rightcol synchroniously.
HTML
<div id="rightcol">
<img name="ImageOnly.src" src='#' />
</div>
<div id="leftcol">
<img src="#" />
</div>
AJAX Script
function ajaxMove(src)
{
var image = '<img src="'+src+'" alt="my transferred image" />';
document.getElementById('rightcol').innerHTML = image;
}
How is it used?
Request the object from the onclick event.
Build an image tag based off the information in the object.
Transfer the new image tag to the element with the id 'rightcol'
Other options
You could also remove the href="#" from the <a> tag and work directly from the onclick event and then apply style="cursor:pointer;". Then it will work like a regular hyperlink but without the refresh.
<a onclick="javascript:ajaxMove('ImageOnly.src')" style="cursor:pointer;" >Click Me</a>

Resources