How to properly replace inline images with styled floating divs via PHP's DOMDocument?
Tag : php , By : Vorinowsky
Date : March 29 2020, 07:55 AM
around this issue As I commented, your code had multiple errors which prevented you from getting started. Your concept looks quite well from what I see and the code itself only had minor issues. You were iterating over the document root element. That's just one element, so picking up all images therein. The second xpath must be relative to the child, so starting with .. If you load in a HTML chunk, DomDocument will create the missing elements like body around it. So you need to address that for your xpath queries and the output. The way you accessed the attributes was wrong. With error reporting on, this would have given you error information about that. $html_from_editor = <<<EOD
<p>Intro Text</p>
<ul>
<li>List point 1</li>
<li>List point 2</li>
</ul>
<p>Some text before an image.
<img alt="Slide 1" src="/files/slide1.png" />
Maybe some text in between, nobody knows what the scientists are up to.
<img alt="Slide 2" src="/files/slide2.png" />
And even more text right after that.
</p>
EOD;
// create DOMDocument
$doc = new DOMDocument();
// load WYSIWYG html into DOMDocument
$doc->loadHTML($html_from_editor);
// create DOMXpath
$xpath = new DOMXpath($doc);
// create list of all first level DOMNodes (these are p's or ul's in most cases)
# NOTE: this is XHTML now
$children = $xpath->query("/html/body/p");
foreach ( $children AS $child ) {
// now get all images
$cpath = new DOMXpath($doc);
$images = $cpath->query('.//img', $child); # NOTE relative to $child, mind the .
// if no images are found, continue
if (!$images->length) continue;
// insert replacement node
$lb_div = $doc->createElement('div');
$lb_div->setAttribute("class", "custom");
$lb_div = $child->parentNode->insertBefore($lb_div, $child);
foreach ( $images AS $img ) {
// get attributes
$atts = $img->attributes;
$atts = (object) iterator_to_array($atts); // make $atts more accessible
// create the new link with lighbox and full view
$lb_a = $doc->createElement('a');
$lb_a->setAttribute("href", '/files/fullview'.$atts->src->value);
$lb_a->setAttribute("rel", "lightbox[slide][".$atts->alt->value."]");
// create the new image tag for thumbnail
$lb_img = $img->cloneNode(); # NOTE clone instead of creating new
$lb_img->setAttribute("src", '/files/thumbs'.$atts->src->value);
// bring the new nodes together and insert them
$lb_a->appendChild($lb_img);
$lb_div->appendChild($lb_a);
// remove the original image
$child->removeChild($img);
}
}
// get body content (original content)
$result = '';
foreach ($xpath->query("/html/body/*") as $child) {
$result .= $doc->saveXML($child); # NOTE or saveHtml
}
echo $result;
|
how to scale divs when i minimize browser so that divs dont collapse over each other
Tag : html , By : bdurbin
Date : March 29 2020, 07:55 AM
With these it helps i have small question. how is it possible to set the heights of 2 divs so that they dont collapse but rather scale dynamically if i minimize the window? i did this in js: , I think you need to bind to the resize event $(document).ready(function(){
var sidebar = document.getElementById('sidebar').offsetHeight;
$(window).resize(function(){
var footer = document.getElementById('footer').offsetHeight;
document.getElementById('sidebar').style.height = sidebar - footer + 'px';
});
});
|
Black space between 2 of my divs. I dont know how to remove them. Have tried a couple of things
Date : March 29 2020, 07:55 AM
fixed the issue. Will look into that further add margin-top: -4px; to .playerName will pull it up and you won't have the space between the two divs. SEE THE FIDDLE
|
Onclick of images add and remove class to multiple Divs
Date : March 29 2020, 07:55 AM
will help you You can reset all these things using jQuery#attr attribute of div. $(".full.swatch-img").on('click',function(){
let colorCode = $(this).attr('id');
$(".adult-section-box .pc-row, .youth-section-box .pc-row")
.attr('class',colorCode+" pc-row");
})
|
How to iterate through hidden divs and scrap text?
Date : March 29 2020, 07:55 AM
should help you out Speech details are loaded using an AJAX request. This means you don't even have to use selenium for this, requests alone is enough, which speeds up things quite a bit: import requests
from bs4 import BeautifulSoup
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'
}
def make_soup(url: str) -> BeautifulSoup:
res = requests.get(url, headers=headers)
res.raise_for_status()
return BeautifulSoup(res.text, 'html.parser')
def fetch_speech_details(speech_id: str) -> str:
url = f'https://pm.gc.ca/eng/views/ajax?view_name=news_article&view_display_id=block&view_args={speech_id}'
res = requests.get(url, headers=headers)
res.raise_for_status()
data = res.json()
html = data[1]['data']
soup = BeautifulSoup(html, 'html.parser')
body = soup.select_one('.views-field-body')
return str(body)
def scrape_speeches(soup: BeautifulSoup) -> dict:
speeches = []
for teaser in soup.select('.teaser'):
title = teaser.select_one('.title').text.strip()
speech_id = teaser['data-nid']
speech_html = fetch_speech_details(speech_id)
s = {
'title': title,
'details': speech_html
}
speeches.append(s)
if __name__ == "__main__":
url = 'https://pm.gc.ca/eng/news/speeches'
soup = make_soup(url)
speeches = scrape_speeches(soup)
from pprint import pprint
pprint(speeches)
[
{'title': 'PM remarks for Lunar Gateway', 'details': '<div class="views-field views-field-body"> <p>CHECK AGAINST DELIVERY</p><p>Hello everyone!</p><p>I’m delighted to be here at the Canadian Space Agency to share some great news with Canadians.</p><p>I’d like to start by thanking the President of the Agency, Sylvain Laporte ... },
{...},
....
]
|