From 84ee539139731fc88244efed8f0d31cd0981a075 Mon Sep 17 00:00:00 2001 From: Quan Dang <18520339@gm.uit.edu.vn> Date: Tue, 30 Jan 2024 04:19:29 +0700 Subject: [PATCH] Update IP hiding techniques knowledge in README.md --- .gitignore | 5 + .../README.md | 67 --- .../.gitignore | 1 - .../LICENSE | 21 - .../README.md | 46 --- .../README.md | 8 - README.md | 387 +++++++++++++++++- assets/nodemaven-test.jpg | Bin 0 -> 61337 bytes assets/token-business.png | Bin 0 -> 98475 bytes .../example.xlsx => devtools-data.xlsx | Bin graph-api/README.md | 59 +++ .../crawler.py | 25 +- .../data}/KTXDHQGConfessions.jsonl | 0 .../data}/devoiminhdidauthe.jsonl | 0 stealth-csr-puppeteer/README.md | 1 + stealth-csr-puppeteer/index.js | 97 +++++ stealth-csr-puppeteer/package.json | 10 + stealth-csr-puppeteer/test.js | 53 +++ stealth-csr-puppeteer/utils.js | 48 +++ .../README.md | 66 ++- .../browser.py | 0 .../crawler.py | 0 .../data/KTXDHQGConfessions.json | 0 .../data/KTXDHQGConfessions.jsonl | 0 .../data/data.json | 0 .../img/filter.png | Bin .../img/proxy.png | Bin .../img/rate_limit_exceeded.png | Bin .../img/result.png | Bin .../page.py | 0 .../requirements.txt | 0 .../tor/linux/PluggableTransports/obfs4proxy | Bin .../tor/linux/libcrypto.so.1.1 | Bin .../tor/linux/libevent-2.1.so.7 | Bin .../tor/linux/libssl.so.1.1 | Bin .../tor/linux/libstdc++/libstdc++.so.6 | Bin .../tor/linux/tor | Bin .../tor/mac/PluggableTransports/obfs4proxy | Bin .../tor/mac/libevent-2.1.7.dylib | Bin .../tor/mac/tor.real | Bin .../PluggableTransports/obfs4proxy.exe | Bin .../tor/windows/libcrypto-1_1-x64.dll | Bin .../tor/windows/libevent-2-1-7.dll | Bin .../tor/windows/libevent_core-2-1-7.dll | Bin .../tor/windows/libevent_extra-2-1-7.dll | Bin .../tor/windows/libgcc_s_seh-1.dll | Bin .../tor/windows/libssl-1_1-x64.dll | Bin .../tor/windows/libssp-0.dll | Bin .../tor/windows/libwinpthread-1.dll | Bin .../tor/windows/tor.exe | Bin .../tor/windows/zlib1.dll | Bin stealth-ssr-puppeteer/README.md | 1 + stealth-ssr-scrapy/README.md | 1 + stealth-ssr-scrapy/fbscraper/__init__.py | 0 stealth-ssr-scrapy/fbscraper/items.py | 12 + stealth-ssr-scrapy/fbscraper/middlewares.py | 103 +++++ stealth-ssr-scrapy/fbscraper/pipelines.py | 13 + stealth-ssr-scrapy/fbscraper/settings.py | 93 +++++ .../fbscraper/spiders/__init__.py | 4 + stealth-ssr-scrapy/scrapy.cfg | 11 + 60 files changed, 922 insertions(+), 210 deletions(-) create mode 100644 .gitignore delete mode 100644 1 - Personal account Access Token with Graph API/README.md delete mode 100644 2 - Automation tools with IP hiding techniques/.gitignore delete mode 100644 2 - Automation tools with IP hiding techniques/LICENSE delete mode 100644 3 - Run JS code directly at the DevTools Console/README.md delete mode 100644 4 - Mbasic Facebook + IP hiding techniques/README.md create mode 100644 assets/nodemaven-test.jpg create mode 100644 assets/token-business.png rename 3 - Run JS code directly at the DevTools Console/example.xlsx => devtools-data.xlsx (100%) create mode 100644 graph-api/README.md rename {1 - Personal account Access Token with Graph API => graph-api}/crawler.py (95%) rename {1 - Personal account Access Token with Graph API => graph-api/data}/KTXDHQGConfessions.jsonl (100%) rename {1 - Personal account Access Token with Graph API => graph-api/data}/devoiminhdidauthe.jsonl (100%) create mode 100644 stealth-csr-puppeteer/README.md create mode 100644 stealth-csr-puppeteer/index.js create mode 100644 stealth-csr-puppeteer/package.json create mode 100644 stealth-csr-puppeteer/test.js create mode 100644 stealth-csr-puppeteer/utils.js rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/README.md (62%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/browser.py (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/crawler.py (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/data/KTXDHQGConfessions.json (100%) rename 2 - Automation tools with IP hiding techniques/data/KTXDHQGConfessions-inline.json => stealth-csr-selenium/data/KTXDHQGConfessions.jsonl (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/data/data.json (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/img/filter.png (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/img/proxy.png (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/img/rate_limit_exceeded.png (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/img/result.png (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/page.py (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/requirements.txt (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/linux/PluggableTransports/obfs4proxy (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/linux/libcrypto.so.1.1 (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/linux/libevent-2.1.so.7 (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/linux/libssl.so.1.1 (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/linux/libstdc++/libstdc++.so.6 (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/linux/tor (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/mac/PluggableTransports/obfs4proxy (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/mac/libevent-2.1.7.dylib (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/mac/tor.real (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/PluggableTransports/obfs4proxy.exe (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/libcrypto-1_1-x64.dll (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/libevent-2-1-7.dll (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/libevent_core-2-1-7.dll (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/libevent_extra-2-1-7.dll (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/libgcc_s_seh-1.dll (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/libssl-1_1-x64.dll (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/libssp-0.dll (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/libwinpthread-1.dll (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/tor.exe (100%) rename {2 - Automation tools with IP hiding techniques => stealth-csr-selenium}/tor/windows/zlib1.dll (100%) create mode 100644 stealth-ssr-puppeteer/README.md create mode 100644 stealth-ssr-scrapy/README.md create mode 100644 stealth-ssr-scrapy/fbscraper/__init__.py create mode 100644 stealth-ssr-scrapy/fbscraper/items.py create mode 100644 stealth-ssr-scrapy/fbscraper/middlewares.py create mode 100644 stealth-ssr-scrapy/fbscraper/pipelines.py create mode 100644 stealth-ssr-scrapy/fbscraper/settings.py create mode 100644 stealth-ssr-scrapy/fbscraper/spiders/__init__.py create mode 100644 stealth-ssr-scrapy/scrapy.cfg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f6a5b80 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +__pycache__ +node_modules/ +tmp/ +.env +package-lock.json \ No newline at end of file diff --git a/1 - Personal account Access Token with Graph API/README.md b/1 - Personal account Access Token with Graph API/README.md deleted file mode 100644 index 0b21c91..0000000 --- a/1 - Personal account Access Token with Graph API/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Personal account Access Token + Graph API - -Use your own Token with **almost full permission** for fetching data. This is the **MOST EFFECTIVE** method. - -> The knowledge and the way to get **Access Token** below is translated from these 2 Vietnamese blogs: -> -> - https://ahachat.com/help/blog/cach-lay-token-facebook -> - https://alotoi.com/get-token-full-quyen - -## Knowledge - -### I. What is Facebook Token? - -The Facebook token is a randomly generated code that contains the data associated with the Facebook account. Facebook Token, also known as **Access Token** will contain the permissions to perform an action on the library (API) provided by Facebook. Each Facebook account will have different **Access Tokens**. There may be 1 or more Tokens on the same Facebook account. - -There are many ways to reach a destination, but for some reason we will have to choose only one, usually the shortest, fastest path. The **Access Token**is a shortcut to that destination. Understand simply Facebook Token is like that. - -### II. What are Facebook tokens used for? - -Facebook Token is now quite popular in the field of Facebook Marketing, depending on the limit of the permissions of each token. Some popular applications of Facebook Token: - -- Increase Facebook likes and subs. -- Automatically post on Facebook. -- Automatically comment, share articles. -- Automatically interact in groups, pages. -- ... - -It is used for many different purposes, but the main goal is still to automate all manual operations. With Facebook Token, you can use some features that Facebook has not yet supported or supported in some countries. For example, you won't be able to do the feature of enabling the Facebook Avatar protection shield without using tokens (or Extensions) if in some other countries (India, Germany, ...), then you will find the option to enable shields right on the Facebook account itself. - -### III. Facebook Token types - -There are 2 types of Facebook Tokens: **Token by App** and **Token by Personal Account**. The Facebook Token by App is the safest one, as it will have a limited lifetime and only has some basic permissions to manipulate on pages and groups. So our main focus will on the Facebook **Token by Personal Account**. - -### IV. Facebook Token by Personal Account - -This is a **full permissions** token represented by a string of characters starting with `EAA...`, the purpose of this token is to represent your Facebook account to perform actions you can do on Facebook, such as sending messages, like pages, and posts to groups through `API`. Compared to **Token by App**, this token has a longer lifetime and more authority. To make it easier to understand what **Token by App** can do, **Token by Personal Account** can also, but not vice versa. - -An example of using this token is that you want to post simultaneously to many groups and many pages; to do this, you cannot log in to each page or group to post because it will be very time-consuming. Just fill in a list of group and page ids, then call an `API` to post them all. Or as you often see on the market, there are tools to increase fake likes, and fake comments are also using this trick. - -Note that using Facebook token can save you time, but you should not disclose this token to others because they can abuse it for bad purposes, by: - -- Do not download extensions to get tokens or login your phone number and password to websites that support getting tokens because your information will be exposed. -- And if you suspect your token has been exposed, immediately change your Facebook password and delete the extensions installed in the browser. Or if you are more careful you can turn on **two-factor authentication** (2FA). - -👉 To ensure the safety of using Facebook tokens for personal purposes and save time, as mentioned above, you should use the method of getting tokens directly on Facebook by following the steps below. - -## Get full permissions Access Token - -In the past, getting Facebook tokens were very simple. Now many Facebook services are developing. Getting Facebook tokens is becoming more and more difficult. Facebook also restricts Full rights tokens to avoid Spam and excessive abuse of user behaviors. Or you can get Token, but it will be limited by basic permissions that we do not use, that is nothing compared to sometimes having an account locked (identity verification). - -Currently, this is the way to use the most. However, it may require you to authenticate with 2FA (via app or SMS Code). With these simple steps, you can get **almost full permission** token. - -- Go to https://business.facebook.com/content_management. -- Press `Ctrl + U`, then `Ctrl + F` to find the code that contains `EAAG`. Copy the highlighted text, that's the Token you need to get. - - ![](https://alotoi.com/wp-content/uploads/2020/08/token-business.png) - -- You can go to this [facebook link](https://developers.facebook.com/tools/debug/accesstoken) to check the permissions of the above token. - ![](https://lh4.googleusercontent.com/0S64t2sjFXjkX8HUjo2GeEW8hyKL88G4lMXkpNF7RgtFCRm0oVPRT--vnoM1rkMyhrRvvHufW9J0ZeP8tPxfo4j5vYityQFM0m06NTI2hq4zk1JMp59W9voHXHYtOjE7zqDGMlhh) - -**Note**: I only share how to get **Access Token** from Facebook itself. Revealing tokens can seriously affect your Facebook account. Please refrain from getting tokens from unknown sources! - -## Implement data extraction with Graph API - -The source of this method is reused from [FBMediaDownloader](https://github.com/HoangTran0410/FBMediaDownloader) with a few more features added - -Updating... diff --git a/2 - Automation tools with IP hiding techniques/.gitignore b/2 - Automation tools with IP hiding techniques/.gitignore deleted file mode 100644 index ed8ebf5..0000000 --- a/2 - Automation tools with IP hiding techniques/.gitignore +++ /dev/null @@ -1 +0,0 @@ -__pycache__ \ No newline at end of file diff --git a/2 - Automation tools with IP hiding techniques/LICENSE b/2 - Automation tools with IP hiding techniques/LICENSE deleted file mode 100644 index 35c9ca1..0000000 --- a/2 - Automation tools with IP hiding techniques/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Quan Dang - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/3 - Run JS code directly at the DevTools Console/README.md b/3 - Run JS code directly at the DevTools Console/README.md deleted file mode 100644 index 88282c2..0000000 --- a/3 - Run JS code directly at the DevTools Console/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Run JS code directly at the DevTools Console - -Simply to say, this method is just another automation one, the same as the [2nd method](#2) but without using any IP hiding techniques. You just directly write & run JS code in the [DevTools Console](https://developer.chrome.com/docs/devtools/open) of your browser, so it's quite convenient, not required to setup anything. - -- You can take a look at this [extremely useful project](https://github.com/jayremnt/facebook-scripts-dom-manipulation) which includes many automation scripts (not just about data extraction) with no Access Token needed for Facebook users by directly manipulating the DOM. - -- Here's my example script to collect comments on **a Facebook page when not sign-in**: - -```js -// Go to the page you want to collect, wait until it finishes loading. -// Open the DevTools Console on the Browser and run the following code -let csvContents = [['UserId', 'Name', 'Comment']]; -let cmtsSelector = '.userContentWrapper .commentable_item'; - -// 1. Click see more comments -// If you want more, just wait until the loading finishes and run this again -moreCmts = document.querySelectorAll(cmtsSelector + ' ._4sxc._42ft'); -moreCmts.forEach(btnMore => btnMore.click()); - -// 2. Collect all comments -comments = document.querySelectorAll(cmtsSelector + ' ._72vr'); -comments.forEach(cmt => { - let info = cmt.querySelector('._6qw4'); - let userId = info.getAttribute('href')?.substring(1); - let content = cmt.querySelector('._3l3x>span')?.innerText; - csvContents.push([userId, info.innerText, content]); -}); -csvContents.map(cmt => cmt.join('\t')).join('\n'); -``` - -
- - - Example result for the script above - -
- -| UserId | Name | Comment | -| -------------- | -------------- | ---------------------------------- | -| freedomabcxyz | Freedom | Sau khi dùng | -| baodendepzai123 | Bảo Huy Nguyễn | nhưng mà thua | -| tukieu.2001 | Tú Kiều | đang xem hài ai rãnh xem quãng cáo | -| ABCDE2k4 | Maa Vănn Kenn | Lê Minh Nhất | -| buikhanhtoanpro | Bùi Khánh Toàn | Haha | - -
\ No newline at end of file diff --git a/4 - Mbasic Facebook + IP hiding techniques/README.md b/4 - Mbasic Facebook + IP hiding techniques/README.md deleted file mode 100644 index 4a338d5..0000000 --- a/4 - Mbasic Facebook + IP hiding techniques/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Mbasic Facebook + IP hiding techniques - -There is also another way quite similar to the [2nd method](#2) is to use the [Mbasic Facebook](https://mbasic.facebook.com): -- This version of Facebook is made for mobile browsers on slow internet connections. You can access it without a modern smartphone. -- With modern devices, it will improves the page loading time & the contents will be rendered with raw HTML, not JS ➔ You can leverage the power of many web scraping tools ([scrapy](https://scrapy.org), [bs4](https://pypi.org/project/beautifulsoup4), ...) not just automation tools like the [2nd method](#2) and it will become even more powerful when used with [IP hiding techniques](https://github.com/18520339/facebook-data-extraction/tree/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques#ii-ip-hiding-techniques). -- You can get each part of the contents through different URLs, not only through the page scrolling like the [2nd method](#2) ➔ You can do something like using proxy for each request or [AutoThrottle](https://doc.scrapy.org/en/latest/topics/autothrottle.html) (a built-in [scrapy](https://scrapy.org) extension), ... - -**Note**: I haven't tried the extraction with this method yet, so I won't go into details about it. \ No newline at end of file diff --git a/README.md b/README.md index ef12d26..dc1671c 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,382 @@ -# Summary of Facebook data extraction methods +# Summary of Facebook data extraction approaches -### I. General Comparison +> I'm editing everything to match the latest big changes -| Method | Sign-in required | Risk when sign-in | Risk when not sign-in | Difficulty | Speed | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------: | :--------------------------------------------------------------------------------------------------------: | :---------------------: | :--------: | :-------------: | -| 1️⃣  [Personal account Access Token + Graph API](https://github.com/18520339/facebook-data-extraction/tree/master/1%20-%20Personal%20account%20Access%20Token%20with%20Graph%20API) | ✅ | Access Token leaked, [Rate Limits](https://developers.facebook.com/docs/graph-api/overview/rate-limiting/) | Not working | Easy | Fast | -| 2️⃣  [Automation tools + IP hiding techniques](https://github.com/18520339/facebook-data-extraction/tree/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques) | Depend **(\*)** | Checkpoint but less _loading more_ failure | Safest | Hard | Slow **(\*\*)** | -| 3️⃣  [Run JS code directly at the DevTools Console](https://github.com/18520339/facebook-data-extraction/tree/master/3%20-%20Run%20JS%20code%20directly%20at%20the%20DevTools%20Console) | Depend **(\*)** | Checkpoint but less _loading more_ failure | Can be banned if abused | Medium | Slow **(\*\*)** | -| 4️⃣  [Mbasic Facebook + IP hiding techniques](https://github.com/18520339/facebook-data-extraction/tree/master/4%20-%20Mbasic%20Facebook%20+%20IP%20hiding%20techniques) | Depend **(\*)** | - | - | Hard | - | +## Overview -**(\*)** Depend on the tasks that you need to sign in to perform. Example: Tasks that need to access private groups or private posts, ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ApproachSign-in required from the startRisk when sign-in (*)Risk when not sign-inDifficultySpeed
1️⃣  Graph API + Full-permission TokenAccess Token leaked + Rate LimitsNot workingEasyFast
2️⃣  SSR - Server-side RenderingCheckpoint but less loading more failure HardMedium
3️⃣  CSR - Client-side RenderingWhen access private contentSafestSlow
4️⃣  DevTools ConsoleCan be banned if overusedMedium
-**(\*\*)** Depend on how much data you want to extract, the more the number, the more times for scrolling down to load the contents. +### I. My general conclusion after many tries with different approaches -### II. My general conclusion after many tries with different methods +When run at **not sign-in** state, Facebook usually redirects to the login page or prevent you from loading more comments/replies. -- When run at **not sign-in** state, Facebook usually redirects to the login page or prevent you from loading more comments / replies. -- No matter which method you use, any fast or irregular activity continuously in **sign-in** state for a long time can be likely to get blocked at any time. -- If you want to use at **sign-in** state, for safety, I recommend create a **fake account** (you can use a [Temporary Email Address](https://temp-mail.org/en/) to create one) and use it for the extraction. -- With the **sign-in** state, there's also another technique to limit the Checkpoint is to sign in with different **Cookies**. +**(*)** For safety when testing with **sign-in** state, I recommend create a **fake account** (you can use a [Temporary Email Address](https://temp-mail.org/en/) to create one) and use it for the extraction, because: +- No matter which approach you use, any fast or irregular activity continuously in **sign-in** state for a long time can be likely to get blocked at any time. -### III. DISCLAIMER +- Authenticating via services with lack of encryption such as proxies using **HTTP** protocol can have potential security risks, especially if sensitive data is being transmitted: + - Therefore, if you are experimenting with your own account, it's advisable to use **HTTPS** proxies or other more secure methods like `VPNs`. + - I won't implement these types of risky authentication into the sign-in process for approaches in this repo, but you can do it yourself if you want. + +### II. DISCLAIMER All information provided in this repo and related articles are for educational purposes only. So use at your own risk, I will not guarantee & not be responsible for any situations including: - Whether your Facebook account may get Checkpoint due to repeatedly or rapid actions. - Problems that may occur or for any abuse of the information or the code provided. -- Problems about your privacy while using [IP hiding techniques](https://github.com/18520339/facebook-data-extraction/tree/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques#ii-ip-hiding-techniques) or any malicious scripts. +- Problems about your privacy while using [IP hiding techniques](#i-ip-hiding-techniques) or any malicious scripts. + +## APPROACH 1. Graph API with Full-permission Token + +👉 Check out my implementation for this approach with [Python](./graph-api/). + +You will query [Facebook Graph API](https://developers.facebook.com/docs/graph-api) using your own Token with **full permission** for fetching data. This is the **MOST EFFECTIVE** approach. + +> The knowledge and the way to get **Access Token** below are translated from these 2 Vietnamese blogs: +> +> - https://ahachat.com/help/blog/cach-lay-token-facebook +> - https://alotoi.com/get-token-full-quyen + +### I. What is Facebook Token? + +A Facebook **Access Token** is a randomly generated code that contains data linked to a Facebook account. It contains the permissions to perform an action on the library (API) provided by Facebook. Each Facebook account will have different **Access Tokens**, and there can be ≥ 1 Tokens on the same account. + +Depending on the limitations of each Token's permissions, which are generated for use with corresponding features, either many or few, they can be used for various purposes, but the main goal is to automate all manual operations. Some common applications include: + +- Increasing likes, subscriptions on Facebook. +- Automatically posting on Facebook. +- Automatically commenting and sharing posts. +- Automatically interacting in groups and Pages. +- ... + +There are 2 types of Facebook Tokens: **App-based Token** and **Personal Account-based Token**. The Facebook **Token by App** is the safest one, as it will have a limited lifetime and only has some basic permissions to interact with `Pages` and `Groups`. Our main focus will on the Facebook **Personal Account-based Token**. + +### II. Personal Account-based Access Token + +This is a **full permissions** Token represented by a string of characters starting with `EAA...`. The purpose of this Token is to act on behalf of your Facebook account to perform actions you can do on Facebook, such as sending messages, liking pages, and posting in groups through `API`. + +Compared to an **App-based Token**, this type of Token has a longer lifespan and more permissions. Simply put, whatever an **App-based Token** can do, a **Personal Account-based Token** can do as well, but not vice versa. + +An example of using this Facebook Token is when you want to simultaneously post to many `Groups` and `Pages`. To do this, you cannot simply log into each `Group` or `Page` to post, which is very time-consuming. Instead, you just need to fill in a list of `Group` and `Page` IDs, and then call an `API` to post to all in this list. Or, as you can often see on the Internet, there are tools to increase fake likes and comments also using this technique. + +Note that using Facebook Token can save you time, but you should not reveal this Token to others as they can misuse it for malicious purposes: + +- Do not download extensions to get Tokens or login with your phone number and password on websites that support Token retrieval, as your information will be compromised. +- And if you suspect your Token has been compromised, immediately change your Facebook password and delete the extensions installed in the browser. +- If you wanna be more careful, you can turn on **two-factor authentication** (2FA). + +👉 To ensure safety when using the Facebook Token for personal purposes and saving time as mentioned above, you should obtain the Token directly from Facebook following the steps below. + +### III. Get Access Token with full permissions + +Before, obtaining Facebook Tokens was very simple, but now many Facebook services are developing and getting Facebook Tokens has become more difficult. Facebook also limits Full permission Tokens to prevent Spam and excessive abuse regarding user behavior. + +It's possible to obtain a Token, but it might be limited by basic permissions that we do not use. This is not a big issue compared to sometimes having accounts locked (identity verification) on Facebook. + +Currently, this is the most used method, but it may require you to authenticate with 2FA (via app or SMS Code). With these following steps, you can get an **almost full permission** Token: + +- Go to https://business.facebook.com/business_locations. +- Press `Ctrl + U`, then `Ctrl + F` to find the code that contains `EAAG`. Copy the highlighted text, that's the Token you want to obtain. + + ![](./assets/token-business.png) + +- You can go to this [facebook link](https://developers.facebook.com/tools/debug/accesstoken) to check the permissions of the above Token. + ![](https://lh4.googleusercontent.com/0S64t2sjFXjkX8HUjo2GeEW8hyKL88G4lMXkpNF7RgtFCRm0oVPRT--vnoM1rkMyhrRvvHufW9J0ZeP8tPxfo4j5vYityQFM0m06NTI2hq4zk1JMp59W9voHXHYtOjE7zqDGMlhh) + +**Note**: I only share how to get **Access Token** from Facebook itself. Revealing Tokens can seriously affect your Facebook account. Please don't get Tokens from unknown sources! + + +## APPROACH 2. SSR - Server-side Rendering + +👉 Check out my implementation using 2 [scraping tools](#scraping-tools) for this approach: [Scrapy](./stealth-ssr-scrapy/) (Implementing) and [Puppeteer](./stealth-ssr-puppeteer/) (Implementing). + +### I. What is Server-side Rendering? + +This is a popular technique for rendering a normally client-side only single-page application (`SPA`) on the **Server** and then sending a fully rendered page to the client. The client's `JavaScript` bundle can then take over and the `SPA` can operate as normal: + +```mermaid +%%{init: {'theme': 'default', 'themeVariables': { 'primaryColor': '#333', 'lineColor': '#666', 'textColor': '#333', }}}%% +sequenceDiagram + participant U as 🌐 User's Browser + participant S as 🔧 Server + participant SS as 📜 Server-side Scripts + participant D as 📚 Database + participant B as 🖥️ Browser Engine + participant H as 💧 Hydration (SPA) + + rect rgb(235, 248, 255) + U->>S: 1. Request 🌐 (URL/Link) + Note right of S: Server processes the request + S->>SS: 2. Processing 🔄 (PHP, Node.js, Python, Ruby, Java) + SS->>D: Execute Business Logic & Query DB + D-->>SS: Return Data + SS-->>S: 3. Rendering 📄 (Generate HTML) + S-->>U: 4. Response 📤 (HTML Page) + end + + rect rgb(255, 243, 235) + U->>B: 5. Display 🖥️ + Note right of B: Browser parses HTML, CSS, JS + B-->>U: Page Displayed to User + end + + alt 6. Hydration (if SPA) + rect rgb(235, 255, 235) + U->>H: Hydration 💧 + Note right of H: Attach event listeners\nMake page interactive + H-->>U: Page now reactive + end + end +``` + +1. The **user's browser** requests a page. +2. The **Server** receives and processes request. This involves running necessary **Server-side scripts**, which can be written in languages like *PHP*, *Node.js*, *Python*, ... +3. These **Server-side scripts** dynamically generate the `HTML` content of the page. This may include executing business logic or querying a database. +4. The **Server** responds by sending the **fully-rendered HTML** page back to **user's browser**. This response also includes `CSS` and the `JS`, which will be process once the `HTML` is loaded. +5. The **user's browser** receives the `HTML` response and renders the page. The browser's rendering engine parses the `HTML`, `CSS`, and execute `JS` to display the page. +6. (Optional) If the application is a `SPA` using a framework like *React*, *Vue*, or *Angular*, an additional process called **Hydration** may occur to attach event listeners to the existing **Server-rendered HTML**: + - This is where the client-side `JS` takes over and `binds` event handlers to the **Server-rendered HTML**, effectively turning a static page into a dynamic one. + - This allows the application to handle user interactions, manage `state`, and potentially update the `DOM` without the need to render a new page from scratch or return to the **Server** for every action. + +| Pros | Cons | +| --------------------------- | --------------------------- | +| - Improved initial load time as users see a **fully-rendered page** sooner, which is important for experience, particularly on slow connections | - More **Server** resources are used to generate the **fully-rendered HTML**. | +| - Improved SEO as search engine crawlers can see the **fully-rendered page**. | - Complex to implement as compared to [CSR](#approach-3-csr---client-side-rendering), especially for dynamic sites where content changes frequently. | + +### II. [Mbasic Facebook](https://mbasic.facebook.com) - A Facebook SSR version + +This Facebook version is made for mobile browsers on slow internet connection by using [SSR](#i-what-is-server-side-rendering) to focus on delivering content in raw `HTML` format. You can access it without a modern smartphones. With modern devices, it will improves the page loading time & the contents will be mainly rendered using raw `HTML` rather than relying heavily on `JS`: + +https://github.com/18520339/facebook-data-extraction/assets/50880271/ae2635ff-3f2a-4b84-a5b3-c126102a0118 + +- You can leverage the power of many web scraping frameworks like [scrapy](https://scrapy.org) not just automation tools like [puppeteer](https://github.com/puppeteer/puppeteer) or [selenium](https://github.com/seleniumhq/selenium) and it will become even more powerful when used with [IP hiding techniques](#i-ip-hiding-techniques). +- You can get each part of the contents through different URLs, not only through the page scrolling ➔ You can do something like using proxy for each request or [AutoThrottle](https://docs.scrapy.org/en/latest/topics/autothrottle.html) (a built-in [scrapy](https://scrapy.org) extension), ... + +Updating... + +## APPROACH 3. CSR - Client-side Rendering + +👉 Check out my implementation using 2 [scraping tools](#scraping-tools) for this approach: [Selenium](./stealth-csr-selenium/) (Deprecated) and [Puppeteer](./stealth-csr-puppeteer/) (Implementing). + +Updating... + + +## APPROACH 4. DevTools Console + +This is the most simple way, which is to directly write & run JS code in the [DevTools Console](https://developer.chrome.com/docs/devtools/open) of your browser, so it's quite convenient, not required to setup anything. + +- You can take a look at this [extremely useful project](https://github.com/jayremnt/facebook-scripts-dom-manipulation) which includes many automation scripts (not just about data extraction) with no Access Token needed for Facebook users by directly manipulating the DOM. + +- Here's my example script to collect comments on **a Facebook page when not sign-in**: + +```js +// Go to the page you want to collect, wait until it finishes loading. +// Open the DevTools Console on the Browser and run the following code +let csvContents = [['UserId', 'Name', 'Comment']]; +let cmtsSelector = '.userContentWrapper .commentable_item'; + +// 1. Click see more comments +// If you want more, just wait until the loading finishes and run this again +moreCmts = document.querySelectorAll(cmtsSelector + ' ._4sxc._42ft'); +moreCmts.forEach(btnMore => btnMore.click()); + +// 2. Collect all comments +comments = document.querySelectorAll(cmtsSelector + ' ._72vr'); +comments.forEach(cmt => { + let info = cmt.querySelector('._6qw4'); + let userId = info.getAttribute('href')?.substring(1); + let content = cmt.querySelector('._3l3x>span')?.innerText; + csvContents.push([userId, info.innerText, content]); +}); +csvContents.map(cmt => cmt.join('\t')).join('\n'); +``` + +
+ + + Example result for the script above + +
+ +| UserId | Name | Comment | +| -------------- | -------------- | ---------------------------------- | +| freedomabcxyz | Freedom | Sau khi dùng | +| baodendepzai123 | Bảo Huy Nguyễn | nhưng mà thua | +| tukieu.2001 | Tú Kiều | đang xem hài ai rãnh xem quãng cáo | +| ABCDE2k4 | Maa Vănn Kenn | Lê Minh Nhất | +| buikhanhtoanpro | Bùi Khánh Toàn | Haha | + +
+ +## Scraping Tools + +Updating... + + +## Bypassing Bot Detection (When not sign-in) + +Updating... + +👉 Highly recommend: https://github.com/niespodd/browser-fingerprinting + +### I. IP hiding techniques + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TechniqueSpeedCostScaleAnonymityOther RisksAdditional Notes
VPN Service
⭐⭐
⭐⭐
Fast, offers a balance of anonymity and speedUsually paid- Good for small-scale operations.
- May not be suitable for high-volume scraping due to potential IP blacklisting.
- Provides good anonymity and can bypass geo-restriction.
- Potential for IP blacklisting/blocks if the VPN's IP range is known to the target site.
- Service reliability varies.
- Possible activity logs.
Choose a reputable provider to avoid security risks.
TOR Network
⭐⭐
Very slow due to onion routingFree- Fine for small-scale, impractical for time-sensitive/ high-volume scraping due to very slow speed.
- Consider only for research purposes, not scalable data collection.
- Offers excellent privacy.
- Tor exit nodes can be blocked or malicious, like potential for eavesdropping.
-Slowest choice
Public
Wi-Fi

VaryFreeFine for small-scale.Potential for being banned by target sites if scraping is detected.Potential unsecured networksLong distance way solution.
Mobile Network
⭐⭐
Relatively fast but slower speeds on some networksPaid, potential for additional costs.Using mobile IPs can be effective for small-scale scraping, impractical for large-scale.Mobile IPs can change but not an anonymous option since it's tied to your personal account.-Using own data
Private/
Dedicated Proxies

⭐⭐⭐
⭐⭐
(Best)
FastPaid- Best for large-scale operations and professional scraping projects.Offer better performance and reliability with lower risk of blacklisting.Vary in quality- Rotating Proxies are popular choices for scraping as they can offer better speed and a variety of IPs.
- You can use this proxy checker tool to assess your proxy quality
Shared Proxies
⭐⭐⭐
(Free)
⭐⭐
⭐⭐
(Paid)
Slow to ModerateUsually Free or cost-effective for low-volume scraping.Good for basic, small-scale, or non-critical scraping tasks.Can be overloaded or blacklisted or, encountering already banned IPs.Potential unreliable/ insecure proxies, especially Free ones.
+ +**IMPORTANT**: Nothing above is absolutely safe and secure. _Caution is never superfluous_. You will need to research more about them if you want to enhance the security of your data and privacy. + +### II. Private/Dedicated Proxies (Most effective IP hiding technique) + +As you can conclude from the table above, **Rotating Private/Dedicated Proxies** is the most effective IP hiding technique for **undetectable** and **large-scale** scraping. Below are 2 popular ways to effectively integrate this technique into your scraping process: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TechniqueSpeedCostScaleAnonymityAdditional Notes
Residential Rotating Proxies
⭐⭐⭐
⭐⭐
(Best)
FastPaidIdeal for high-end, large-scale scraping tasks.- Mimics real user IPs and auto-rotate IPs when using proxy gateways, making detection harder.
- Provides high anonymity and low risk of blacklisting/blocks due to legitimate residential IPs.
Consider proxy quality, location targeting, and rotation speed.
Datacenter Rotating Proxies
⭐⭐
⭐⭐
Faster than Residential ProxiesMore affordable than Residential ProxiesGood for cost-effective, large-scale scraping.Less anonymous than Residential Proxies.
- Higher risk of being blocked.
- Easily detectable due to their datacenter IP ranges.
Consider reputation of the provider and frequency of IP rotation.
+ +Recently, I experimented my web scraping [npm package](https://www.npmjs.com/package/puppeteer-ecommerce-scraper) with [NodeMaven](https://nodemaven.com/?a_aid=quandang), a **Residential proxy provider** with a focus on IP quality as well as stability, and I think it worked quite well. Below is the proxy quality result that I tested using the [proxy checker tool](https://addons.mozilla.org/en-US/firefox/addon/proxy-checker/) I mentioned [above](#i-ip-hiding-techniques): + +![](./assets/nodemaven-test.jpg) + +And this is the performance measure of my actual run that I tested with my [scraping package](https://www.npmjs.com/package/puppeteer-ecommerce-scraper): + +- **Successful scrape runs**: 96% (over 100 attempts). This result is a quite good. + - [NodeMaven](https://nodemaven.com/?a_aid=quandang) already reduced the likelihood of encountering banned or blacklisted IPs through the `IP Quality Filtering` feature. + - Another reason is that it can access to over `5M residential IPs` across 150+ countries, a broad range of geo-targeting options. + - I also used their `IP Rotation` feature to rotate IPs within a single gateway endpoint, which simplified my scraping setup and provided consistent anonymity. +- **Average scrape time**: around 1-2 mins/10 pages for complex dynamic loading website (highly dependent on website complexity). While the proxy speeds were generally consistent, there were occasional fluctuations, which is expected in any proxy service. +- **Sticky Sessions**: 24h+ session durations allowed me to maintain connections and complete scrapes efficiently. +- **IP block rate** / **Redirect** / **Blank page** in the first run: <4%. + +Overall, throughout many runs, the proxies proved to be reliable with minimal downtime or issues. For those interested in trying [NodeMaven](https://nodemaven.com/?a_aid=quandang), you can apply the code `QD2` for an additional 2GB of traffic free with your trial or package purchase. + +### II. Browser Settings & Plugins + +Updating... + diff --git a/assets/nodemaven-test.jpg b/assets/nodemaven-test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..632cc4b791ffa0613a91892ccbe2f2b03cb94eb8 GIT binary patch literal 61337 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 B%AWuL literal 0 HcmV?d00001 diff --git a/assets/token-business.png b/assets/token-business.png new file mode 100644 index 0000000000000000000000000000000000000000..c5e07b1f86ecc0eaa035fa361bee099fc4b4973f GIT binary patch literal 98475 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 { + const cluster = await Cluster.launch({ + concurrency: Cluster.CONCURRENCY_BROWSER, + maxConcurrency, + puppeteer, + perBrowserOptions: Array.from({ length: maxConcurrency }, (_, i) => ({ + ...puppeteerOptions, + // userDataDir: `./tmp/profile${i}`, // For each browser, use a different profile + })), + monitor: true, + timeout: 1e5, + }); + + cluster.on('taskerror', (err, data) => { + console.log(err.message, JSON.stringify(data)); + }); + + await cluster.task(async ({ page, data: { url, permissions } }) => { + const browser = page.browser(); + const context = browser.defaultBrowserContext(); + await context.overridePermissions(url, permissions); + + const pagesArray = await browser.pages(); + const notBlankPage = pagesArray[0]; + await page.close(pagesArray[1]); + + if (PROXY_USERNAME && PROXY_PASSWORD) + await notBlankPage.authenticate({ username: PROXY_USERNAME, password: PROXY_PASSWORD }); + await notBlankPage.goto(url, { waitUntil: 'load' }); + + const products = []; + const keyword = new URL(url).searchParams.get('q'); + const filename = `./data/${keyword}.csv`; + let isBtnDisabled = false; + + fs.writeFile(filename, 'title,price,imgUrl\n', 'utf-8', err => { + if (err) throw err; + console.log(`${filename} created`); + }); + + while (!isBtnDisabled) { + await notBlankPage.waitForSelector('.product-item', { visible: true, hidden: false }); + const productNodes = await notBlankPage.$$('.product-item'); + + for (const node of productNodes) { + const [title, price, imgUrl] = await notBlankPage.evaluate(el => { + return [ + // Code inside `evaluate` runs in the context of the browser + el.querySelector('.product-name')?.textContent.replaceAll(',', ''), + el.querySelector('.price-discount__price')?.textContent.slice(0, -1), + el.querySelector('.product-image img')?.getAttribute('srcset').split(' ')[0], + ]; + }, node); + + if (title && price && imgUrl) { + products.push({ title, price, imgUrl }); + fs.appendFile(filename, `${title},${price},${imgUrl}\n`, 'utf-8', err => { + if (err) throw err; + // console.log(title); + }); + } + } + + isBtnDisabled = (await notBlankPage.$('div:nth-child(3) a.arrow.disabled')) !== null; + if (!isBtnDisabled) + await Promise.all([ + notBlankPage.click('div:nth-child(3) a.arrow'), + notBlankPage.waitForNavigation({ waitUntil: 'domcontentloaded' }), + sleep(1000), + ]); + } + }); + + for (const url of urls) await cluster.queue({ url, permissions: [] }); + await cluster.idle(); + await cluster.close(); +})(); diff --git a/stealth-csr-puppeteer/package.json b/stealth-csr-puppeteer/package.json new file mode 100644 index 0000000..8d0702e --- /dev/null +++ b/stealth-csr-puppeteer/package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "dotenv": "^16.3.2", + "puppeteer": "^21.7.0", + "puppeteer-cluster": "^0.23.0", + "puppeteer-extra": "^3.3.6", + "puppeteer-extra-plugin-stealth": "^2.11.2", + "puppeteer-with-fingerprints": "^1.4.4" + } +} diff --git a/stealth-csr-puppeteer/test.js b/stealth-csr-puppeteer/test.js new file mode 100644 index 0000000..f9e6d99 --- /dev/null +++ b/stealth-csr-puppeteer/test.js @@ -0,0 +1,53 @@ +require('dotenv').config(); +const { PROXY_SERVER, PROXY_USERNAME, PROXY_PASSWORD } = process.env; + +const { Cluster } = require('puppeteer-cluster'); +const { getChromeExecutablePath } = require('./utils'); +const puppeteerOptions = { + headless: false, + defaultViewport: false, + executablePath: getChromeExecutablePath(), // Avoid Bot detection + args: [`--proxy-server=${PROXY_SERVER}`], +}; + +const puppeteer = require('puppeteer-extra'); +const StealthPlugin = require('puppeteer-extra-plugin-stealth'); +puppeteer.use(StealthPlugin()); + +const maxConcurrency = 2; + +(async () => { + const cluster = await Cluster.launch({ + concurrency: Cluster.CONCURRENCY_BROWSER, + maxConcurrency, + puppeteer, + perBrowserOptions: Array.from({ length: maxConcurrency }, (_, i) => ({ + ...puppeteerOptions, + userDataDir: `./tmp/profile${i}`, // For each browser, use a different profile + })), + }); + + cluster.on('taskerror', (err, data) => { + console.log(`Error crawling ${data}: ${err.message}`); + }); + + await cluster.task(async ({ page, data: queueIndex }) => { + console.log(`Running tests for queue ${queueIndex}...`); + if (PROXY_USERNAME && PROXY_PASSWORD) + await page.authenticate({ username: PROXY_USERNAME, password: PROXY_PASSWORD }); + + await page.goto('https://ipinfo.io/json', { waitUntil: 'domcontentloaded' }); + const content = await page.$eval('body', el => el.innerText); + console.log(`IP Information of Queue ${queueIndex}: ${content}`); + + await page.goto('https://bot.sannysoft.com', { waitUntil: 'networkidle2' }); + const ssPath = `./tmp/bot${queueIndex}.png`; + await page.screenshot({ path: ssPath, fullPage: true }); + console.log(`Check ${ssPath} for anti-bot testing result of Queue ${queueIndex}`); + }); + + for (let i = 0; i < maxConcurrency; i++) await cluster.queue(i); + await cluster.idle(); + await cluster.close(); + console.log('All done ✨'); +})(); diff --git a/stealth-csr-puppeteer/utils.js b/stealth-csr-puppeteer/utils.js new file mode 100644 index 0000000..c924b5c --- /dev/null +++ b/stealth-csr-puppeteer/utils.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const os = require('os'); + +const sleep = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds)); + +// Cannot use the same profile for multiple browsers => Not working with CONCURRENCY_BROWSER +function getChromeProfilePath() { + const homePath = os.homedir(); + switch (os.platform()) { + case 'win32': // Windows + return `${homePath}\\AppData\\Local\\Google\\Chrome\\User Data\\Default`; + case 'darwin': // macOS + return `${homePath}/Library/Application Support/Google/Chrome/Default`; + case 'linux': // Linux + return `${homePath}/.config/google-chrome/Default`; + default: + throw new Error('Unsupported platform'); + } +} + +function getChromeExecutablePath() { + const isFileExists = path => { + try { + fs.accessSync(path, fs.constants.F_OK); + return true; + } catch (e) { + return false; + } + }; + + switch (os.platform()) { + case 'win32': // Windows + const paths = [ + 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', + 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe', + ]; + for (let path of paths) if (isFileExists(path)) return path; + throw new Error('Chrome executable not found in expected locations on Windows'); + case 'darwin': // macOS + return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'; + case 'linux': // Linux + return '/usr/bin/google-chrome'; + default: + throw new Error('Unsupported platform'); + } +} + +module.exports = { getChromeProfilePath, getChromeExecutablePath, sleep }; diff --git a/2 - Automation tools with IP hiding techniques/README.md b/stealth-csr-selenium/README.md similarity index 62% rename from 2 - Automation tools with IP hiding techniques/README.md rename to stealth-csr-selenium/README.md index 061cea3..514af31 100644 --- a/2 - Automation tools with IP hiding techniques/README.md +++ b/stealth-csr-selenium/README.md @@ -1,29 +1,15 @@ -# Automation tools + IP hiding techniques +# CSR Approach using Selenium (DEPRECATED) -In this method, I will write example scripts to extract id, user info, content, date, comments, and replies of posts. +> My scripts for this approach were made in 2020, so it's now deprecated with the new Facebook UI. But you can use it as a reference for other similar implementations with Selenium. -**Note**: These scripts just working for **a Facebook page when not sign-in**, not group or any other object. +In this approach, I will write example scripts to extract id, user info, content, date, comments, and replies of posts. -> Demo: https://www.youtube.com/watch?v=Fx0UWOzYsig +👉 Demo: https://www.youtube.com/watch?v=Fx0UWOzYsig -## Knowledge +**Note**: -### I. Automation tools - -Updating... - -### II. IP hiding techniques - -| Method | Speed rating | Cost | Common risk | General Evaluation | -| ------------ | :----------: | ------------ | --------------------------------------- | ------------------ | -| VPN service | `2` | Usually paid | Some free providers might not be secure | Best way | -| Tor browser | `4` | Free | Can be tracked by some rogue nodes | Slowest choice | -| Proxy server | `3` | Usually free | Data routing not private as VPNs | Riskiest method | -| Public WiFi | `1` | Free | Some might not be safe | Long distance way | - -➔ Learn more about general information of above methods from this [site](https://whatismyipaddress.com/hide-ip). - -**IMPORTANT**: Nothing above is absolutely safe and secure. *Carefulness is never excessive*. You will need to do further research about them if you want more secure to your data & privacy. +- These scripts just working for **a Facebook page when not sign-in**, not group or any other object. +- Maybe you will need to edit some of the CSS Selectors in the scripts, as Facebook might have changed them at the time of your use. ## Overview the scripts @@ -34,34 +20,34 @@ Updating... 3. Checking redirect. 4. Can be run with Incognito window. 5. Simplifying browser to minimize time complexity. -6. Delay with random intervals every *loading more* times to simulate human behavior. +6. Delay with random intervals every _loading more_ times to simulate human behavior. 7. Not required sign-in to **prevent Checkpoint**. 8. Hiding IP address to **prevent from banning** by: - - Collecting proxies and filtering the slowest ones from: + - Collecting Proxies and filtering the slowest ones from: - http://proxyfor.eu/geo.php - http://free-proxy-list.net - http://rebro.weebly.com/proxy-list.html - http://www.samair.ru/proxy/time-01.htm - https://www.sslproxies.org - - [Tor Relays](https://github.com/18520339/facebook-crawling/tree/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques/tor) which used in [Tor Browser](https://www.torproject.org/), a network is comprised of thousands of volunteer-run servers. + - [Tor Relays](./tor/) which used in [Tor Browser](https://www.torproject.org/), a network is comprised of thousands of volunteer-run servers. ### II. Weaknesses - Unable to detect some failed responses. Example: **Rate limit exceeded** (Facebook prevents from loading more). - - ![](https://github.com/18520339/facebook-crawling/blob/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques/img/rate_limit_exceeded.png?raw=true) + + ![](./img/rate_limit_exceeded.png?raw=true) ➔ Have to run with `HEADLESS = False` to detect manually. -- Quite slow when running with a large number of _loading more_ or when using [IP hiding techniques](#ii-ip-hiding-techniques). +- Quite slow when running with a large number of _loading more_ or when using [IP hiding techniques](https://github.com/18520339/facebook-data-extraction/tree/master/#i-ip-hiding-techniques). ### III. Result -- Each post will be separated [line by line](https://raw.githubusercontent.com/18520339/facebook-crawling/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques/data/KTXDHQGConfessions-inline.json). +- Each post will be separated [line by line](./data/KTXDHQGConfessions.jsonl). - Most of my successful tests were on **Firefox** with [HTTP Request Randomizer](https://github.com/pgaref/HTTP_Request_Randomizer) proxy server. - My latest run on **Firefox** with **Incognito** windows using [HTTP Request Randomizer](https://github.com/pgaref/HTTP_Request_Randomizer): - ![](https://github.com/18520339/facebook-crawling/blob/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques/img/result.png?raw=true) + ![](./img/result.png?raw=true)
@@ -110,12 +96,12 @@ Updating... - [Helium](https://github.com/mherrmann/selenium-python-helium): a wrapper around [Selenium](https://selenium-python.readthedocs.io/) with more high-level API for web automation. - [HTTP Request Randomizer](https://github.com/pgaref/HTTP_Request_Randomizer): used for collecting free proxies. -### II. Customize parameters in [crawler.py](https://github.com/18520339/facebook-crawling/blob/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques/crawler.py) +### II. Customize CONFIG VARIABLES in [crawler.py](./crawler.py) -1. **Running browser**: +1. **Running the Browser**: - - **PAGE_URL**: url of Facebook page. - - **TOR_PATH**: use proxy with Tor for `WINDOWS` / `MAC` / `LINUX` / `NONE`: + - **PAGE_URL**: URL of Facebook page. + - **TOR_PATH**: use Proxy with Tor for `WINDOWS` / `MAC` / `LINUX` / `NONE`: - **BROWSER_OPTIONS**: run scripts using `CHROME` / `FIREFOX`. - **PRIVATE**: run with private mode or not: - Prevent from **Selenium** detection ➔ **navigator.driver** must be _undefined_ (check in Dev Tools). @@ -150,11 +136,11 @@ Updating... browser_options.set_preference('dom.ipc.plugins.enabled.libflashplayer.so', 'false') ``` -2. **Loading page**: +2. **Loading the Page**: - **SCROLL_DOWN**: number of times to scroll for **view more posts**. - **FILTER_CMTS_BY**: filter comments by `MOST_RELEVANT` / `NEWEST` / `ALL_COMMENTS`. - ![](https://github.com/18520339/facebook-crawling/blob/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques/img/filter.png?raw=true) + ![](./img/filter.png?raw=true) - **VIEW_MORE_CMTS**: number of times to click **view more comments**. - **VIEW_MORE_REPLIES**: number of times to click **view more replies**. @@ -163,10 +149,10 @@ Updating... python crawler.py - Run at sign out state, cause some CSS Selectors will be different as sign in. -- With some proxies, it might be quite slow or required to sign in (redirected). +- With some Proxies, it might be quite slow or required to sign in (redirected). - **To achieve higher speed**: - - If this is first time using these scripts, you can **run without tor & proxies** until Facebook requires to sign in. - - Use some popular **VPN services** (also **run without tor & proxies**): [NordVPN](https://nordvpn.com), [ExpressVPN](https://www.expressvpn.com), ... + - If this is first time using these scripts, you can **run without Tor & Proxies** until Facebook requires to sign in. + - Use some popular **VPN services** (also **run without Tor & Proxies**): [NordVPN](https://ref.nordvpn.com/dnaEbnXnysg), [ExpressVPN](https://www.expressvpn.com), ... ## Test proxy server @@ -182,7 +168,7 @@ setup_free_proxy(page_url, proxy_server, browser_options) # kill_browser() ``` -2. With [Tor Relays](https://github.com/18520339/facebook-crawling/tree/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques/tor): +2. With [Tor Relays](./tor): ```python from browser import * @@ -194,4 +180,4 @@ setup_tor_proxy(page_url, tor_path, browser_options) # kill_browser() ``` -![](https://github.com/18520339/facebook-crawling/blob/master/2%20-%20Automation%20tools%20with%20IP%20hiding%20techniques/img/proxy.png?raw=true) \ No newline at end of file +![](./img/proxy.png?raw=true) diff --git a/2 - Automation tools with IP hiding techniques/browser.py b/stealth-csr-selenium/browser.py similarity index 100% rename from 2 - Automation tools with IP hiding techniques/browser.py rename to stealth-csr-selenium/browser.py diff --git a/2 - Automation tools with IP hiding techniques/crawler.py b/stealth-csr-selenium/crawler.py similarity index 100% rename from 2 - Automation tools with IP hiding techniques/crawler.py rename to stealth-csr-selenium/crawler.py diff --git a/2 - Automation tools with IP hiding techniques/data/KTXDHQGConfessions.json b/stealth-csr-selenium/data/KTXDHQGConfessions.json similarity index 100% rename from 2 - Automation tools with IP hiding techniques/data/KTXDHQGConfessions.json rename to stealth-csr-selenium/data/KTXDHQGConfessions.json diff --git a/2 - Automation tools with IP hiding techniques/data/KTXDHQGConfessions-inline.json b/stealth-csr-selenium/data/KTXDHQGConfessions.jsonl similarity index 100% rename from 2 - Automation tools with IP hiding techniques/data/KTXDHQGConfessions-inline.json rename to stealth-csr-selenium/data/KTXDHQGConfessions.jsonl diff --git a/2 - Automation tools with IP hiding techniques/data/data.json b/stealth-csr-selenium/data/data.json similarity index 100% rename from 2 - Automation tools with IP hiding techniques/data/data.json rename to stealth-csr-selenium/data/data.json diff --git a/2 - Automation tools with IP hiding techniques/img/filter.png b/stealth-csr-selenium/img/filter.png similarity index 100% rename from 2 - Automation tools with IP hiding techniques/img/filter.png rename to stealth-csr-selenium/img/filter.png diff --git a/2 - Automation tools with IP hiding techniques/img/proxy.png b/stealth-csr-selenium/img/proxy.png similarity index 100% rename from 2 - Automation tools with IP hiding techniques/img/proxy.png rename to stealth-csr-selenium/img/proxy.png diff --git a/2 - Automation tools with IP hiding techniques/img/rate_limit_exceeded.png b/stealth-csr-selenium/img/rate_limit_exceeded.png similarity index 100% rename from 2 - Automation tools with IP hiding techniques/img/rate_limit_exceeded.png rename to stealth-csr-selenium/img/rate_limit_exceeded.png diff --git a/2 - Automation tools with IP hiding techniques/img/result.png b/stealth-csr-selenium/img/result.png similarity index 100% rename from 2 - Automation tools with IP hiding techniques/img/result.png rename to stealth-csr-selenium/img/result.png diff --git a/2 - Automation tools with IP hiding techniques/page.py b/stealth-csr-selenium/page.py similarity index 100% rename from 2 - Automation tools with IP hiding techniques/page.py rename to stealth-csr-selenium/page.py diff --git a/2 - Automation tools with IP hiding techniques/requirements.txt b/stealth-csr-selenium/requirements.txt similarity index 100% rename from 2 - Automation tools with IP hiding techniques/requirements.txt rename to stealth-csr-selenium/requirements.txt diff --git a/2 - Automation tools with IP hiding techniques/tor/linux/PluggableTransports/obfs4proxy b/stealth-csr-selenium/tor/linux/PluggableTransports/obfs4proxy similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/linux/PluggableTransports/obfs4proxy rename to stealth-csr-selenium/tor/linux/PluggableTransports/obfs4proxy diff --git a/2 - Automation tools with IP hiding techniques/tor/linux/libcrypto.so.1.1 b/stealth-csr-selenium/tor/linux/libcrypto.so.1.1 similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/linux/libcrypto.so.1.1 rename to stealth-csr-selenium/tor/linux/libcrypto.so.1.1 diff --git a/2 - Automation tools with IP hiding techniques/tor/linux/libevent-2.1.so.7 b/stealth-csr-selenium/tor/linux/libevent-2.1.so.7 similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/linux/libevent-2.1.so.7 rename to stealth-csr-selenium/tor/linux/libevent-2.1.so.7 diff --git a/2 - Automation tools with IP hiding techniques/tor/linux/libssl.so.1.1 b/stealth-csr-selenium/tor/linux/libssl.so.1.1 similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/linux/libssl.so.1.1 rename to stealth-csr-selenium/tor/linux/libssl.so.1.1 diff --git a/2 - Automation tools with IP hiding techniques/tor/linux/libstdc++/libstdc++.so.6 b/stealth-csr-selenium/tor/linux/libstdc++/libstdc++.so.6 similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/linux/libstdc++/libstdc++.so.6 rename to stealth-csr-selenium/tor/linux/libstdc++/libstdc++.so.6 diff --git a/2 - Automation tools with IP hiding techniques/tor/linux/tor b/stealth-csr-selenium/tor/linux/tor similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/linux/tor rename to stealth-csr-selenium/tor/linux/tor diff --git a/2 - Automation tools with IP hiding techniques/tor/mac/PluggableTransports/obfs4proxy b/stealth-csr-selenium/tor/mac/PluggableTransports/obfs4proxy similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/mac/PluggableTransports/obfs4proxy rename to stealth-csr-selenium/tor/mac/PluggableTransports/obfs4proxy diff --git a/2 - Automation tools with IP hiding techniques/tor/mac/libevent-2.1.7.dylib b/stealth-csr-selenium/tor/mac/libevent-2.1.7.dylib similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/mac/libevent-2.1.7.dylib rename to stealth-csr-selenium/tor/mac/libevent-2.1.7.dylib diff --git a/2 - Automation tools with IP hiding techniques/tor/mac/tor.real b/stealth-csr-selenium/tor/mac/tor.real similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/mac/tor.real rename to stealth-csr-selenium/tor/mac/tor.real diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/PluggableTransports/obfs4proxy.exe b/stealth-csr-selenium/tor/windows/PluggableTransports/obfs4proxy.exe similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/PluggableTransports/obfs4proxy.exe rename to stealth-csr-selenium/tor/windows/PluggableTransports/obfs4proxy.exe diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/libcrypto-1_1-x64.dll b/stealth-csr-selenium/tor/windows/libcrypto-1_1-x64.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/libcrypto-1_1-x64.dll rename to stealth-csr-selenium/tor/windows/libcrypto-1_1-x64.dll diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/libevent-2-1-7.dll b/stealth-csr-selenium/tor/windows/libevent-2-1-7.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/libevent-2-1-7.dll rename to stealth-csr-selenium/tor/windows/libevent-2-1-7.dll diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/libevent_core-2-1-7.dll b/stealth-csr-selenium/tor/windows/libevent_core-2-1-7.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/libevent_core-2-1-7.dll rename to stealth-csr-selenium/tor/windows/libevent_core-2-1-7.dll diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/libevent_extra-2-1-7.dll b/stealth-csr-selenium/tor/windows/libevent_extra-2-1-7.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/libevent_extra-2-1-7.dll rename to stealth-csr-selenium/tor/windows/libevent_extra-2-1-7.dll diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/libgcc_s_seh-1.dll b/stealth-csr-selenium/tor/windows/libgcc_s_seh-1.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/libgcc_s_seh-1.dll rename to stealth-csr-selenium/tor/windows/libgcc_s_seh-1.dll diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/libssl-1_1-x64.dll b/stealth-csr-selenium/tor/windows/libssl-1_1-x64.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/libssl-1_1-x64.dll rename to stealth-csr-selenium/tor/windows/libssl-1_1-x64.dll diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/libssp-0.dll b/stealth-csr-selenium/tor/windows/libssp-0.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/libssp-0.dll rename to stealth-csr-selenium/tor/windows/libssp-0.dll diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/libwinpthread-1.dll b/stealth-csr-selenium/tor/windows/libwinpthread-1.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/libwinpthread-1.dll rename to stealth-csr-selenium/tor/windows/libwinpthread-1.dll diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/tor.exe b/stealth-csr-selenium/tor/windows/tor.exe similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/tor.exe rename to stealth-csr-selenium/tor/windows/tor.exe diff --git a/2 - Automation tools with IP hiding techniques/tor/windows/zlib1.dll b/stealth-csr-selenium/tor/windows/zlib1.dll similarity index 100% rename from 2 - Automation tools with IP hiding techniques/tor/windows/zlib1.dll rename to stealth-csr-selenium/tor/windows/zlib1.dll diff --git a/stealth-ssr-puppeteer/README.md b/stealth-ssr-puppeteer/README.md new file mode 100644 index 0000000..5e6466a --- /dev/null +++ b/stealth-ssr-puppeteer/README.md @@ -0,0 +1 @@ +# SSR Approach using Puppeteer \ No newline at end of file diff --git a/stealth-ssr-scrapy/README.md b/stealth-ssr-scrapy/README.md new file mode 100644 index 0000000..b93fad5 --- /dev/null +++ b/stealth-ssr-scrapy/README.md @@ -0,0 +1 @@ +# SSR Approach using Scrapy \ No newline at end of file diff --git a/stealth-ssr-scrapy/fbscraper/__init__.py b/stealth-ssr-scrapy/fbscraper/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/stealth-ssr-scrapy/fbscraper/items.py b/stealth-ssr-scrapy/fbscraper/items.py new file mode 100644 index 0000000..2b019cc --- /dev/null +++ b/stealth-ssr-scrapy/fbscraper/items.py @@ -0,0 +1,12 @@ +# Define here the models for your scraped items +# +# See documentation in: +# https://docs.scrapy.org/en/latest/topics/items.html + +import scrapy + + +class FbscraperItem(scrapy.Item): + # define the fields for your item here like: + # name = scrapy.Field() + pass diff --git a/stealth-ssr-scrapy/fbscraper/middlewares.py b/stealth-ssr-scrapy/fbscraper/middlewares.py new file mode 100644 index 0000000..30bf6d3 --- /dev/null +++ b/stealth-ssr-scrapy/fbscraper/middlewares.py @@ -0,0 +1,103 @@ +# Define here the models for your spider middleware +# +# See documentation in: +# https://docs.scrapy.org/en/latest/topics/spider-middleware.html + +from scrapy import signals + +# useful for handling different item types with a single interface +from itemadapter import is_item, ItemAdapter + + +class FbscraperSpiderMiddleware: + # Not all methods need to be defined. If a method is not defined, + # scrapy acts as if the spider middleware does not modify the + # passed objects. + + @classmethod + def from_crawler(cls, crawler): + # This method is used by Scrapy to create your spiders. + s = cls() + crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) + return s + + def process_spider_input(self, response, spider): + # Called for each response that goes through the spider + # middleware and into the spider. + + # Should return None or raise an exception. + return None + + def process_spider_output(self, response, result, spider): + # Called with the results returned from the Spider, after + # it has processed the response. + + # Must return an iterable of Request, or item objects. + for i in result: + yield i + + def process_spider_exception(self, response, exception, spider): + # Called when a spider or process_spider_input() method + # (from other spider middleware) raises an exception. + + # Should return either None or an iterable of Request or item objects. + pass + + def process_start_requests(self, start_requests, spider): + # Called with the start requests of the spider, and works + # similarly to the process_spider_output() method, except + # that it doesn’t have a response associated. + + # Must return only requests (not items). + for r in start_requests: + yield r + + def spider_opened(self, spider): + spider.logger.info("Spider opened: %s" % spider.name) + + +class FbscraperDownloaderMiddleware: + # Not all methods need to be defined. If a method is not defined, + # scrapy acts as if the downloader middleware does not modify the + # passed objects. + + @classmethod + def from_crawler(cls, crawler): + # This method is used by Scrapy to create your spiders. + s = cls() + crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) + return s + + def process_request(self, request, spider): + # Called for each request that goes through the downloader + # middleware. + + # Must either: + # - return None: continue processing this request + # - or return a Response object + # - or return a Request object + # - or raise IgnoreRequest: process_exception() methods of + # installed downloader middleware will be called + return None + + def process_response(self, request, response, spider): + # Called with the response returned from the downloader. + + # Must either; + # - return a Response object + # - return a Request object + # - or raise IgnoreRequest + return response + + def process_exception(self, request, exception, spider): + # Called when a download handler or a process_request() + # (from other downloader middleware) raises an exception. + + # Must either: + # - return None: continue processing this exception + # - return a Response object: stops process_exception() chain + # - return a Request object: stops process_exception() chain + pass + + def spider_opened(self, spider): + spider.logger.info("Spider opened: %s" % spider.name) diff --git a/stealth-ssr-scrapy/fbscraper/pipelines.py b/stealth-ssr-scrapy/fbscraper/pipelines.py new file mode 100644 index 0000000..e13986b --- /dev/null +++ b/stealth-ssr-scrapy/fbscraper/pipelines.py @@ -0,0 +1,13 @@ +# Define your item pipelines here +# +# Don't forget to add your pipeline to the ITEM_PIPELINES setting +# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html + + +# useful for handling different item types with a single interface +from itemadapter import ItemAdapter + + +class FbscraperPipeline: + def process_item(self, item, spider): + return item diff --git a/stealth-ssr-scrapy/fbscraper/settings.py b/stealth-ssr-scrapy/fbscraper/settings.py new file mode 100644 index 0000000..c7e35b6 --- /dev/null +++ b/stealth-ssr-scrapy/fbscraper/settings.py @@ -0,0 +1,93 @@ +# Scrapy settings for fbscraper project +# +# For simplicity, this file contains only settings considered important or +# commonly used. You can find more settings consulting the documentation: +# +# https://docs.scrapy.org/en/latest/topics/settings.html +# https://docs.scrapy.org/en/latest/topics/downloader-middleware.html +# https://docs.scrapy.org/en/latest/topics/spider-middleware.html + +BOT_NAME = "fbscraper" + +SPIDER_MODULES = ["fbscraper.spiders"] +NEWSPIDER_MODULE = "fbscraper.spiders" + + +# Crawl responsibly by identifying yourself (and your website) on the user-agent +#USER_AGENT = "fbscraper (+http://www.yourdomain.com)" + +# Obey robots.txt rules +ROBOTSTXT_OBEY = True + +# Configure maximum concurrent requests performed by Scrapy (default: 16) +#CONCURRENT_REQUESTS = 32 + +# Configure a delay for requests for the same website (default: 0) +# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay +# See also autothrottle settings and docs +#DOWNLOAD_DELAY = 3 +# The download delay setting will honor only one of: +#CONCURRENT_REQUESTS_PER_DOMAIN = 16 +#CONCURRENT_REQUESTS_PER_IP = 16 + +# Disable cookies (enabled by default) +#COOKIES_ENABLED = False + +# Disable Telnet Console (enabled by default) +#TELNETCONSOLE_ENABLED = False + +# Override the default request headers: +#DEFAULT_REQUEST_HEADERS = { +# "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", +# "Accept-Language": "en", +#} + +# Enable or disable spider middlewares +# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html +#SPIDER_MIDDLEWARES = { +# "fbscraper.middlewares.FbscraperSpiderMiddleware": 543, +#} + +# Enable or disable downloader middlewares +# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html +#DOWNLOADER_MIDDLEWARES = { +# "fbscraper.middlewares.FbscraperDownloaderMiddleware": 543, +#} + +# Enable or disable extensions +# See https://docs.scrapy.org/en/latest/topics/extensions.html +#EXTENSIONS = { +# "scrapy.extensions.telnet.TelnetConsole": None, +#} + +# Configure item pipelines +# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html +#ITEM_PIPELINES = { +# "fbscraper.pipelines.FbscraperPipeline": 300, +#} + +# Enable and configure the AutoThrottle extension (disabled by default) +# See https://docs.scrapy.org/en/latest/topics/autothrottle.html +#AUTOTHROTTLE_ENABLED = True +# The initial download delay +#AUTOTHROTTLE_START_DELAY = 5 +# The maximum download delay to be set in case of high latencies +#AUTOTHROTTLE_MAX_DELAY = 60 +# The average number of requests Scrapy should be sending in parallel to +# each remote server +#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0 +# Enable showing throttling stats for every response received: +#AUTOTHROTTLE_DEBUG = False + +# Enable and configure HTTP caching (disabled by default) +# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings +#HTTPCACHE_ENABLED = True +#HTTPCACHE_EXPIRATION_SECS = 0 +#HTTPCACHE_DIR = "httpcache" +#HTTPCACHE_IGNORE_HTTP_CODES = [] +#HTTPCACHE_STORAGE = "scrapy.extensions.httpcache.FilesystemCacheStorage" + +# Set settings whose default value is deprecated to a future-proof value +REQUEST_FINGERPRINTER_IMPLEMENTATION = "2.7" +TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor" +FEED_EXPORT_ENCODING = "utf-8" diff --git a/stealth-ssr-scrapy/fbscraper/spiders/__init__.py b/stealth-ssr-scrapy/fbscraper/spiders/__init__.py new file mode 100644 index 0000000..ebd689a --- /dev/null +++ b/stealth-ssr-scrapy/fbscraper/spiders/__init__.py @@ -0,0 +1,4 @@ +# This package will contain the spiders of your Scrapy project +# +# Please refer to the documentation for information on how to create and manage +# your spiders. diff --git a/stealth-ssr-scrapy/scrapy.cfg b/stealth-ssr-scrapy/scrapy.cfg new file mode 100644 index 0000000..4c3bce1 --- /dev/null +++ b/stealth-ssr-scrapy/scrapy.cfg @@ -0,0 +1,11 @@ +# Automatically created by: scrapy startproject +# +# For more information about the [deploy] section see: +# https://scrapyd.readthedocs.io/en/latest/deploy.html + +[settings] +default = fbscraper.settings + +[deploy] +#url = http://localhost:6800/ +project = fbscraper