<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Blog]]></title><description><![CDATA[Blog]]></description><link>https://blog.shivy.co.in/</link><image><url>https://blog.shivy.co.in/favicon.png</url><title>Blog</title><link>https://blog.shivy.co.in/</link></image><generator>Ghost 3.19</generator><lastBuildDate>Wed, 22 Jul 2026 16:10:36 GMT</lastBuildDate><atom:link href="https://blog.shivy.co.in/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Scaling scrapers to scrap 10 millions items]]></title><description><![CDATA[<p>Web scraping is an interesting job, finding out imperfections or loop holes in a site that can be used to scrap the website without rate limits. With current webstack framework like react or vue, it gets quite difficult to work with just simple <a href="https://docs.python-requests.org/en/latest/">requests module</a> as it demands rendering of</p>]]></description><link>https://blog.shivy.co.in/scraping-10-million-items-with-scaling/</link><guid isPermaLink="false">61ba2d7752f2e05312d6a76b</guid><dc:creator><![CDATA[Ajay Masi]]></dc:creator><pubDate>Sun, 26 Dec 2021 19:16:37 GMT</pubDate><content:encoded><![CDATA[<p>Web scraping is an interesting job, finding out imperfections or loop holes in a site that can be used to scrap the website without rate limits. With current webstack framework like react or vue, it gets quite difficult to work with just simple <a href="https://docs.python-requests.org/en/latest/">requests module</a> as it demands rendering of javascript to load dom content. It usually ends up with either using selenium to scrap the page content or mess around the network tab to look for any open APIs that can be used.</p><p><strong>But what's next step, after building a scraper? Deployment! </strong><br>Issue with deployment is most of the scrapers I have seen or worked on aren't scalable after some point. Sure they can scrap 10k records from facebook or weibo without getting blocked but that's it. Scaling them vertically is not an option since it binds to the same IP address of machine which can lead to 419 error (<em>too many requests error</em>) or direct block.</p><p>I have heard of many solutions where the links are divided in batches and executed on different machines. While that works, issue is if a machine goes down or I have an extra machine to add, I have to start over again.</p><h3 id="tl-dr-celery-is-the-solution">tl;dr: <a href="https://docs.celeryproject.org/">Celery</a> is the solution<br></h3><blockquote>Celery is a simple, flexible, and reliable distributed system to process vast amounts of messages, while providing operations with the tools required to maintain such a system. It’s a task queue with focus on real-time processing, while also supporting task scheduling.<br>- Celery's homepage</blockquote><p>In one of the recent projects, I had to scrap website with around 338 search pages, and each page containing 100 items and for each item there are around 30-500 comments. <br>Idea is dividing the scraping of single item into basic celery tasks that can be sent over to queue and processed as atomic functions in different machines.</p><figure class="kg-card kg-image-card"><img src="https://blog.shivy.co.in/content/images/2021/12/phase1.png" class="kg-image"></figure><p>A trigger (job adder) script will make a search query in main website and send out the search result pages link to the SCRAP_SEARCH_PAGES worker i.e., </p><!--kg-card-begin: markdown--><pre><code>1. domain.com/?q=iphone&amp;page=1
2. domain.com/?q=iphone&amp;page=2
3. domain.com/?q=iphone&amp;page=3
</code></pre>
<!--kg-card-end: markdown--><p>SCRAP_SEARCH_PAGES will scrap all products links from the passed search page url, and send scraped product links to next worker SCRAP_PRODUCT_INFO. </p><figure class="kg-card kg-image-card"><img src="https://blog.shivy.co.in/content/images/2021/12/Screenshot_20211221_070106.png" class="kg-image"></figure><p><br>SCRAP_PRODUCT_INFO will scrap item's details like title, description, seller etc. and send the generated item json to INSERT_INTO_DB worker.<br><br>And at the same time it will send the item to SCRAP_ITEM_COMMENTS worker, to process the comments as well.</p><p>SCRAP_ITEM_COMMENTS will scrap comments from the item's detail page and send them as json to INSERT_INTO_DB worker.<br><br>Instead of linking each worker with database, I used one db worker cause on scaling out other workers (scraper workers), it will also increase number of db connections hence increasing the load on database server creating a bottleneck. <br>I have measured single db worker running on t3.micro instance and mongo database server running on t3.medium and it was able to reach around ~420 entries per second, which was good enough for the project.</p><h3 id="picking-up-resources">Picking up resources</h3><p>I have used <a href="https://www.rabbitmq.com/">rabbitmq</a> instead of going with <a href="https://redis.com/">redis</a> for celery queue, while redis comes with easy plug an play config I don't think it could have handled 10+ million queue items without creating any latency issue for 35+ workers running at once. I went with rabbitmq for performance reasons and after adding memory swap and resizing allocated in-memory block for queues it worked without any issues on single t3.nano instance.</p><p>For the workers, it depends on what kind of task is being done. Like if it's image processing or uploading to s3 bucket, I'd prefer picking medium or large instance with 2-4 workers. If it's making simple http requests using requests module and <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">bs4</a> parsing, micro instances work well. I picked both micro and large instances with aws <a href="https://aws.amazon.com/autoscaling/#:~:text=AWS%20Auto%20Scaling%20monitors%20your,at%20the%20lowest%20possible%20cost.&amp;text=AWS%20Auto%20Scaling%20is%20available,and%20Amazon%20CloudWatch%20monitoring%20fees.">autoscaling</a> option to scale out instances depending on the size of job queues.<br><br>For easier and faster deployment, I built docker image and pushed everything to aws ecr. I wrote a bash script and put it in user-data so on every start of machine, it will pull the latest image and start worker with given env for queue, listening for queue passed in the $QUEUE env using the below command:</p><!--kg-card-begin: markdown--><pre><code>celery -A proj worker -Q $QUEUE
</code></pre>
<!--kg-card-end: markdown--><h3 id="conclusion">Conclusion</h3><p>There are not many solutions to distributed scraping in the market. I have tested <a href="https://github.com/crawlab-team/crawlab">crawlab</a> and <a href="https://scrapyd.readthedocs.io/en/stable/">scrapyd</a> but they aren't very suitable for large jobs. While this solution is complicated to setup but it promises that no jobs are lost in case of system crash or restarting workers. With this setup, the entire site was scraped in less than a day. Only limit was how much spot instances can be allocated.</p><h3 id="what-we-didn-t-do">What we didn't do</h3><ul><li>Kubernetes setup for better CI/CD</li><li>Automatic scaling based on average cluster load or queue's size</li><li>Cluster monitoring using grafana to get proper utilization metrics of instances</li><li>Centralized logs if in case tasks were failing</li></ul>]]></content:encoded></item><item><title><![CDATA[Shivy won the Microsoft Code for Future hackathon!]]></title><description><![CDATA[Shivy won the Microsoft Code for Future hackathon. In this post, we will share how we won our first hackathon as an organization, what was our idea, project]]></description><link>https://blog.shivy.co.in/shivy-won-microsoft-hackathon/</link><guid isPermaLink="false">5ee0b0c76b006f6addc6e5ff</guid><category><![CDATA[hackathon]]></category><dc:creator><![CDATA[Ganesh Bagaria]]></dc:creator><pubDate>Thu, 19 Nov 2020 21:01:55 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1415594445260-63e18261587e?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html--><strong>Hello everyone,</strong>
<img src="https://images.unsplash.com/photo-1415594445260-63e18261587e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=2000&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Shivy won the Microsoft Code for Future hackathon!"><p>A while ago, we took part in <a href="https://www.microsoft.com/en-in/codeforfuture" target="_blank"><i>Microsoft Code for future</i></a> open source hackathon as <strong>Road Busters</strong> and in this post we will share our experience with you.</p>

<p>In general <i>Microsoft Code for future hackathon</i> was all about <strong>Smart Traffic Management system for Quick Commute and carbon reduction</strong>. We had to develop a system to smartly control the traffic for quick commutation and to reduce the carbon emission using Azure service and Open Source technologies.</p><!--kg-card-end: html--><p></p><!--kg-card-begin: html--><h2>Existing System</h2>
<hr>

<h4>Traffic control system in Indian cities is not smart.</h4>

<img src="https://blog.shivy.co.in/content/images/2020/07/hack.jpg" style="display: block; margin:auto;" alt="Shivy won the Microsoft Code for Future hackathon!">

<ul>
	<li>They don’t adapt to the dynamic situation of the continuously changing traffic.</li>
	<li>Most common traffic systems use a pre-set timer which turns the traffic signal red/green after a specified delay.</li>
    <li>The vehicles have to wait for a long time span even if the traffic density is very less which leads to increase in Carbon emission rate and increase the density of traffic.</li>
</ul><!--kg-card-end: html--><p></p><!--kg-card-begin: html--><h2>Our Idea</h2>
<hr>

<p>Now to control the traffic smartly and reduce the carbon emission rate, we came up with an idea of passing the vehicles as soon as they reach the junction.</p>

<p><img src="https://blog.shivy.co.in/content/images/2020/07/rsz_hack2-min.png" style="display: block; margin:auto;" width="73%" alt="Shivy won the Microsoft Code for Future hackathon!"></p>

<p>In other words, suppose a vehicle takes 2 minutes to reach crossroad B from crossroad A, then crossroad B shouldn’t turn green for vehicles that are coming from the direction of crossroad A for 2 minutes.</p>

<p>And in between those 2 minutes, crossroad B could be green for vehicles that are not coming from the direction of crossroad A.</p>

<p>In order to make it possible. We would need to know about the distance between crossroad A and crossroad B. With that we will able to find the average time a vehicle will take to reach crossroad B from crossroad A with average speed of 30 - 40 km/hr. We would also need the location of all traffic junctions.</p>

<p>With all that data we will able to build a system which would be able to control the traffic smartly and will reduce the carbon emission rate without any external hardware need.</p>

<h4>In Technical Terms</h4>

<p><img src="https://blog.shivy.co.in/content/images/2020/07/rsz_hack1-min.png" style="display: block; margin:auto;" width="40%" alt="Shivy won the Microsoft Code for Future hackathon!"></p>

<p>If we assume roads as pipelines carrying water and each junction as valve which opens/closes to control the flow of the water. 
We can map logic to the roads such that only X amount of vehicles are passing through given location at a given point of time.</p>

<!--kg-card-end: html--><p></p><!--kg-card-begin: html--><h2>Implementing the idea</h2>
<hr>

<p>Firstly, we collected all the traffic junction location data and an area of Ahmedabad (a city in India) from Openstreet map.</p>

<p>We had to be creative, because we couldn't find all traffic junction locations.Cause this project was just to showcase how our idea will smartly control the traffic and how it will reduce carbon emission rate. Thus, manually we had to add traffic junction locations at each crossroad.</p>

<p>Then we used that data within our own GUI built on top of javascript to help us simulate how traffic will be affected with the new implementation.</p>

<p>It also helped in tuning the delay values to get least possible waiting time at each junction where traffic light is present.</p>

<p>Just like we implemented our idea for dummy data, we can implement it into the real world scenario and reduce the emission rate of carbon.</p><!--kg-card-end: html--><p></p><!--kg-card-begin: html--><h2>Challenges faced while building the system</h2>
<hr>

<ul>
    <li>The biggest challenge we faced was to find and collect valid data (all the traffic lights position in a city) and somehow integrate them in UI such that cars also follow that rule.
    We didn’t get the data we were looking for, hence we created another tool and filled up the traffic light positions manually.</li>

	<div>
        <p style="margin-top: 20px;">
            <img src="https://blog.shivy.co.in/content/images/2020/07/rsz_hack4-min.png" style="margin: 0px 0px 0px 70px; float:left;" alt="Shivy won the Microsoft Code for Future hackathon!">
            <img src="https://blog.shivy.co.in/content/images/2020/07/rsz_hack3-min.png" style="padding: 0px 0px 0px 150px;" alt="Shivy won the Microsoft Code for Future hackathon!">
        </p>
    </div>

    <li>The other challenge was the UI itself like how to teach cars when to move or stop when there is green light or red light.
        For solving this challenge, we checked the distance of each car if it's near any traffic light
        <ul>
            <li>if yes, then check if the nearest traffic light is red
                <ul>
                    <li>if yes, then stop the car</li>
                    <li>else go ahead</li>
                </ul>
            </li>
        </ul>
    </li>
</ul><!--kg-card-end: html--><p></p><!--kg-card-begin: html--><h2>Deployment</h2>
<hr>

<p>Here comes the deployment of our smart traffic simulation system. We used heroku for the deployment. As we were using Express.js server and it was a small-scale project without much processing, memory consumption.</p>

<p><strong>Feel free to check out our project <a href="https://traffic-holder.herokuapp.com/">here</a>.</strong></p><!--kg-card-end: html--><p></p><!--kg-card-begin: html--><h2>Technologies used and why?</h2>
<hr>

<h5><a href="https://docs.aiohttp.org/" target="_blank">Python with AioHTTP</a></h5>
<p>We used AioHTTP library to get the route data. We used it instead of requests for making asynchronous request, non-blocking I/O calls, and for the fast results.</p>

<h5><a href="https://mappa.js.org/" target="_blank">Mappa library</a></h5>
<p>We used Mappa library in order to work with the static map. It allow us to overlay a canvas on top of a tile map.</p>

<h5><a href="https://p5js.org/" target="_blank">p5.js library</a></h5>
<p>We used p5.js for creating graphic within the web page.</p>

<h5><a href="https://leafletjs.com/" target="_blank">Leaflet.js library</a></h5>
<p>We used Leaflet.js for creating markers/cars in the map.</p>

<h5><a href="https://wiki.openstreetmap.org/wiki/Pyroute" target="_blank">Route finding library</a></h5>
<p>We used Pyroute routing library to find the shortest path between two crossroads.</p>

<h5><a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a></h5>
<p>We used OpenStreetMap for getting the map/tiles of an area of Ahmedabad city.</p>

<h5><a href="https://overpass-turbo.eu/" target="_blank">Overpass Turbo</a></h5>
<p>Overpass turbo (overpass-turbo.eu) is a web based data mining tool for OpenStreetMap. We used it to get distance between crossroads and for getting the location of the crossroads.</p><!--kg-card-end: html--><p></p><!--kg-card-begin: html--><h2>Some Q/A</h2>
<hr>

<ul>
    <li>
        <strong>How will this project make the earth more greener?</strong>
        <ul>
            <li>We are trying to reduce the waiting time at each traffic junction without any extra hardware or software by adjusting the timers of the city to take into account the traffic amount from their adjacent junctions.</li>
            <li>With less waiting time there’ll be less wastage of fuel.</li>
        </ul>
    </li>
    <li>
        <strong>Will it require any extra hardware like other adaptive solutions?</strong>
        <ul>
            <li>No, it won’t require any extra hardware for the first phase.</li>
            <li>We can calculate value of traffic light of each junction in the city on one serve and can change them in the city accordingly.</li>
            <li>For next phase, we can add microcontroller to change the values dynamically when server updates the value from its end.</li>
        </ul>
    </li>
    <li>
        <strong>Can it also adapt to rush hours and weekend traffic automatically?</strong>
        <ul>
            <li>At phase one it can’t, but once we add microcontroller to automatically update time from server it can handle rush hours and weekend traffic based on previously collected dataset.</li>
        </ul>
    </li>
    <li>
        <strong>Will it also help when there’s sudden traffic change?</strong>
        <ul>
            <li>No, it can’t help in such situation.</li>
            <li>We need to add crowd detection module to detect crown at each junction and trigger traffic lights.</li>
        </ul>
    </li>
</ul><!--kg-card-end: html--><p></p><!--kg-card-begin: html--><blockquote>
<h4>AM aka Ajay's Experience in his own words -</h4>
<p>It was all in a rush when Endo called me and suggested that we should register in Microsoft’s Code for Future hackathon on 10th of March (last day of registration).</p>

<p>There was this idea that I had been pondering over whenever I stopped at a red light at a traffic junction; like if somehow my timings were correct along with my vehicle’s speed. I could reach home without encountering any red light or in the least amount of them.</p>

<p>I occasionally did find at some point the perfect timing, if I left my office by 19:00 and hit the road by 19:15 I was able to avoid most of the red lights that I encountered on other days.</p>

<p>With this hackathon, we got a chance to work on this and even though we didn’t exactly complete it, we know that it is possible to build a system without the need of any extra hardware or image recognition cameras to regulate traffic with existing technology if we tweak timings accordingly.</p>
</blockquote><!--kg-card-end: html--><p></p><!--kg-card-begin: html--><p>We hope you found this post interesting and helpful.</p>

<p>Link to <a href="https://traffic-holder.herokuapp.com/">Our Project</a></p>

<p><strong>Thank you so much for reading this post.</strong></p><!--kg-card-end: html-->]]></content:encoded></item></channel></rss>