Premiär! Fyndchans i SweClockers Månadens Drop

Kontrollera annonser automatiskt med beautifulsoup4

Permalänk
Medlem

Kontrollera annonser automatiskt med beautifulsoup4

Hej!

Jag försöker mig på webscraping, mest för det är kul. Så jag tänkte att jag skulle bygga ett skript som kollar sweclockers var 5 minut efter annonser på datorer.

Mitt problem just nu är att jag inte lyckas förstå vad det är jag ska skicka till sweclockers.
Från Firefox developer tools så ser jag att när jag gör en POST genom att trycka "sök i marknaden", så skickas följande:
-------------------------------------------------------------------------------
POST /marknad/sok HTTP/1.1
Host: www.sweclockers.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://www.sweclockers.com/marknad
Content-Type: application/x-www-form-urlencoded
Content-Length: 104
Cookie: __couid=4f456a3d-7254-49eb-9697-396bdd44d3c3; __codnp=
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

query
catid=1
locid=0
action=doSearch
typeid[]=1
typeid[]=2
typeid[]=3
typeid[]=4
csrf
-------------------------------------------------------------------------------
Det är sedan en 302 som skickas så man får begära den nya sidan med en GET.

Så jag provade att skicka detta genom postman men får då endast tillbaka ursprungssidan utan sorterat resultat. Detta nedan är headern jag får, vilket inte har något redirect.
-------------------------------------------------------------------------------
Accept-Ranges →bytes
Age →0
Cache-Control →max-age=300, no-store, must-revalidate
Connection →keep-alive
Content-Encoding →gzip
Content-Length →17406
Content-Type →text/html; charset=UTF-8
Date →Thu, 19 Jul 2018 20:42:35 GMT
Expires →Thu, 19 Jul 2018 22:47:35 +0200
Pragma →Cache
Server →Apache
Vary →Accept-Encoding,X-Session
Via →1.1 varnish-v4
X-Cache →MISS
X-Srv →1
X-Varnish →200074202
-------------------------------------------------------------------------------
Varför då?

Har någon av er gjort detta eller kan ge mig ett tips?

Permalänk
Hedersmedlem

När du skickar med postman, skickar du formdatan precis som du visat? För det verkar saknas lite grejer där, som försvunnit i copy paste. Måste vara urlencodat.

Permalänk
Hedersmedlem
Skrivet av aradove:

Hej!

Jag försöker mig på webscraping, mest för det är kul. Så jag tänkte att jag skulle bygga ett skript som kollar sweclockers var 5 minut efter annonser på datorer.

Mitt problem just nu är att jag inte lyckas förstå vad det är jag ska skicka till sweclockers.
Från Firefox developer tools så ser jag att när jag gör en POST genom att trycka "sök i marknaden", så skickas följande:
-------------------------------------------------------------------------------
POST /marknad/sok HTTP/1.1
Host: www.sweclockers.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://www.sweclockers.com/marknad
Content-Type: application/x-www-form-urlencoded
Content-Length: 104
Cookie: __couid=4f456a3d-7254-49eb-9697-396bdd44d3c3; __codnp=
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

query
catid=1
locid=0
action=doSearch
typeid[]=1
typeid[]=2
typeid[]=3
typeid[]=4
csrf
-------------------------------------------------------------------------------
Det är sedan en 302 som skickas så man får begära den nya sidan med en GET.

Så jag provade att skicka detta genom postman men får då endast tillbaka ursprungssidan utan sorterat resultat. Detta nedan är headern jag får, vilket inte har något redirect.
-------------------------------------------------------------------------------
Accept-Ranges →bytes
Age →0
Cache-Control →max-age=300, no-store, must-revalidate
Connection →keep-alive
Content-Encoding →gzip
Content-Length →17406
Content-Type →text/html; charset=UTF-8
Date →Thu, 19 Jul 2018 20:42:35 GMT
Expires →Thu, 19 Jul 2018 22:47:35 +0200
Pragma →Cache
Server →Apache
Vary →Accept-Encoding,X-Session
Via →1.1 varnish-v4
X-Cache →MISS
X-Srv →1
X-Varnish →200074202
-------------------------------------------------------------------------------
Varför då?

Har någon av er gjort detta eller kan ge mig ett tips?

Jag är inte riktigt med på vad du vill posta till sidan.
Ifall du bara vill få ut alla annonser skulle jag rekommendera att kolla på vår RSS feed för marknaden, så har du dessutom lite mindre data att behöva parse'a.
Vill passa på och säga att du får tänka på hur ofta du hämtar data och inte göra det mer än nödvändigt (titta på cache expire header i svaret och använd det).

Mvh // Anton

Visa signatur

Dator, MOBO: Asus X99-A, CPU: Intel I7 6800k (3.4GHz), GPU: Geforce PNY 2070 Super, RAM: 4x8GB Corsair Vengeance LPX 2400MHz, OS-HDD: Intel 750 PCIe 400GB, PSU: EVGA SuperNOVA G2 850W

Permalänk
Medlem

@Klorixx:

Själva poängen är att jag vill prova på webscraping. Annonserna är väl egentligen bara ett bihang. Absolut så ska jag kolla hur länge de är giltiga

Det kanske är samma sak med en rss feedback, men kan man sortera ut endast en kategori med det?

Permalänk
Medlem

@pv2b:

I postman fyller man i fält så formatera den resten åt en.

Permalänk
Legendarisk

@aradove: Scraping brukar inte vara helt populärt så om du vill experimentera med något riktigt så kan det vara klokt att begränsa sig till GET:s efter vanliga sidor så att du varken råkar överbelasta någon eller får dig själv blockerad. Här är ett exempel som visar aktiva trådar istället (du kan se på dess svarsheaders att den redan cachas av Varnish – mycket snällare än att söka):

import requests import bs4 response = requests.get("https://www.sweclockers.com/forum/aktiva") if response.status_code == 200: html = bs4.BeautifulSoup(response.text, "html.parser") for row in (html .find("div", {"class": "forumThreads"}) .findAll("tr", {"class": "forumThread"}) ): h2 = row.find("h2") print(h2.a.getText()) print(h2.a["href"]); print()

Beautifulsoup har dock inte stöd för XPath, vilket kan göra det ganska tradigt att navigera mer komplicerade dokument; är du intresserad av att scrapa eller att överhuvudtaget extrahera data från XML så rekommenderar jag att du tittar närmare på det. Här är ett exempel som gör samma sak som ovanstående, fast via lxml istället:

import requests from lxml import etree from io import StringIO response = requests.get("https://www.sweclockers.com/forum/aktiva") if response.status_code == 200: parser = etree.HTMLParser() doc = etree.parse(StringIO(response.text), parser) for row in doc.xpath("//div[contains(@class, 'forumThreads')]//tr"): for heading in row.xpath(".//h2/a"): print(heading.text) print(heading.attrib["href"]) print()

1600x - första gången jag överklockar /forum/trad/1524442-1600x-forsta-gangen-jag-overklockar Ghost S1 - prestanda, format, community /forum/trad/1470645-ghost-s1-prestanda-format-community Grafikkort i handbagaget på flyget? /forum/trad/1519865-grafikkort-i-handbagaget-pa-flyget Playerunknown's Battlegrounds /forum/trad/1467980-playerunknowns-battlegrounds Pixel 2 skickad på lagning av skärm /forum/trad/1524265-pixel-2-skickad-pa-lagning-av-skarm Fungerar dem här komponenterna ihop? /forum/trad/1524462-fungerar-dem-har-komponenterna-ihop FläktClockers: hur håller ni era hem svalna i hettan? /forum/trad/1524322-flaktclockers-hur-haller-ni-era-hem-svalna-i-hettan ...

Output

Vill du ändå följa marknaden så har SweClockers en RSS för kategorin Datorer, skulle tro att @Klorixx blir mycket gladare på dig om du använder den istället, och du kan hämta och söka igenom den med samma tekniker som ovan.

https://www.sweclockers.com/feeds/marknad/kategori/1

Visa signatur

Abstractions all the way down.

Permalänk
Medlem
Skrivet av Biberu:

@aradove: Scraping brukar inte vara helt populärt så om du vill experimentera med något riktigt så kan det vara klokt att begränsa sig till GET:s efter vanliga sidor så att du varken råkar överbelasta någon eller får dig själv blockerad. Här är ett exempel som visar aktiva trådar istället (du kan se på dess svarsheaders att den redan cachas av Varnish – mycket snällare än att söka):

import requests import bs4 response = requests.get("https://www.sweclockers.com/forum/aktiva") if response.status_code == 200: html = bs4.BeautifulSoup(response.text, "html.parser") for row in (html .find("div", {"class": "forumThreads"}) .findAll("tr", {"class": "forumThread"}) ): h2 = row.find("h2") print(h2.a.getText()) print(h2.a["href"]); print()

Beautifulsoup har dock inte stöd för XPath, vilket kan göra det ganska tradigt att navigera mer komplicerade dokument; är du intresserad av att scrapa eller att överhuvudtaget extrahera data från XML så rekommenderar jag att du tittar närmare på det. Här är ett exempel som gör samma sak som ovanstående, fast via lxml istället:

import requests from lxml import etree from io import StringIO response = requests.get("https://www.sweclockers.com/forum/aktiva") if response.status_code == 200: parser = etree.HTMLParser() doc = etree.parse(StringIO(response.text), parser) for row in doc.xpath("//div[contains(@class, 'forumThreads')]//tr"): for heading in row.xpath(".//h2/a"): print(heading.text) print(heading.attrib["href"]) print()

1600x - första gången jag överklockar /forum/trad/1524442-1600x-forsta-gangen-jag-overklockar Ghost S1 - prestanda, format, community /forum/trad/1470645-ghost-s1-prestanda-format-community Grafikkort i handbagaget på flyget? /forum/trad/1519865-grafikkort-i-handbagaget-pa-flyget Playerunknown's Battlegrounds /forum/trad/1467980-playerunknowns-battlegrounds Pixel 2 skickad på lagning av skärm /forum/trad/1524265-pixel-2-skickad-pa-lagning-av-skarm Fungerar dem här komponenterna ihop? /forum/trad/1524462-fungerar-dem-har-komponenterna-ihop FläktClockers: hur håller ni era hem svalna i hettan? /forum/trad/1524322-flaktclockers-hur-haller-ni-era-hem-svalna-i-hettan ...

Output

Vill du ändå följa marknaden så har SweClockers en RSS för kategorin Datorer, skulle tro att @Klorixx blir mycket gladare på dig om du använder den istället, och du kan hämta och söka igenom den med samma tekniker som ovan.

https://www.sweclockers.com/feeds/marknad/kategori/1

Tack!

Det var bra info. Men kan jag sortera på samma sätt som i när jag trycker sök? För det är svårt att bygga ett filter när det oftast bara är komponentnamn i titeln.

Skickades från m.sweclockers.com

Permalänk
Legendarisk

@aradove: Generellt sett: Nej, det kan du inte. Det beror helt på vad siten du kommunicerar med har stöd för. Du kan försöka undersöka vad som går på en specifik site t.ex. genom att titta på vilka interna länkar som finns, gå igenom din webbläsares nätverkslogg, prova dig fram (fungerar samma parametrar på RSS:en som på den vanliga marknadsavdelningen?), eller helt enkelt att prata med admin. Helst vill du ha ett API som kan exportera den information du behöver i maskinvänlig form, att scrapa är en sista utväg om du inte kan få tag i datan på annat sätt, men om syftet är att lära sig det så...

Vill inte posta kod för att söka, men ett alternativ är att bevaka RSS:en för hela marknaden och varje gång du ser en ny annons så scrapar du bara den sidan efter de uppgifter du saknar, och notifierar sedan på något sätt om du får en träff på vad du letar efter. Du skulle även kunna indexera informationen lokalt hos dig, och sedan söka mot din egen databas istället för via webbformuläret. Att scrapa involverar ofta sådana steg så det är nyttigt det med.

Visa signatur

Abstractions all the way down.

Permalänk
Medlem

@Biberu:

Jo det är ett alternativ förstås. Är webscraping krävande för servrar, eller är det så att man inte gillar dem?
Jag kan ju börja med rss feeden.

Alternativt funderade jag på KTH:s hemsidor. Ofta så uppdaterar lärarna hemsidorna utan att berätta för oss studenter (frustrerande). Då skulle jag kunna kontrollera om websidan uppdaterats, men det kräver dock att jag loggar in vilket inte fungerade för mig senast då jag försökte.

Hur skulle ni göra för att kontrollera efter ändringar på en hemsida?

Permalänk
Legendarisk
Skrivet av aradove:

Är webscraping krävande för servrar, eller är det så att man inte gillar dem?

Det är inte mer krävande än annan trafik, men om du på ett automatiserat sätt ber en server utföra tyngre uppgifter likt sökningar så äter du upp en oproportionerligt stor andel av resurserna, sådana formulär brukar vara throttlade (vilket t.ex. kan få dig blockerad) eller försedda med captchas för att förhindra det, men I värsta fall kan du råka ta så mycket resurser i anspråk att övriga användare påverkas. Därtill tar många betalt för sina tjänster genom att visa annonser, och får ingen ersättning om du läser av siterna maskinellt. Därför brukar scraping vara impopulärt. Tänk på etiketten.

Skrivet av aradove:

Hur skulle ni göra för att kontrollera efter ändringar på en hemsida?

Hade gjort precis som jag skrev i mitt förra inlägg.

Visa signatur

Abstractions all the way down.