Nhà viết kịch lấy văn bản python

Một bài viết ngắn có tiêu đề Phát hiện Chrome Headless đã xuất hiện trên Hacker News vào cuối tuần qua và kể từ đó nó đã được lan truyền rộng rãi. Hầu hết các cuộc thảo luận trên Hacker News đều tập trung xung quanh khẳng định có phần mơ hồ của tác giả rằng quét web là một “nhiệm vụ độc hại” thuộc cùng loại với gian lận quảng cáo và hack trang web. Đó luôn là một cuộc tranh luận thú vị để tham gia, nhưng điều mà tôi thực sự quan tâm về bài báo là nó ngầm thúc đẩy ý tưởng chặn người dùng dựa trên dấu vân tay của trình duyệt. Theo như tôi được biết, đây thường là một ý tưởng tồi tệ và bạn có nhiều khả năng chặn và làm người dùng của mình thất vọng hơn là cung cấp bất kỳ hình thức ngăn chặn có ý nghĩa nào đối với những người mà bạn đang cố gắng chặn

Để minh họa điểm này, tôi đã triển khai tất cả các thử nghiệm được đề xuất trong Phát hiện Chrome Headless và không có gì ngạc nhiên khi trình duyệt tiêu chuẩn hàng ngày của tôi đã không thực hiện được một số thử nghiệm

Nhà viết kịch lấy văn bản python

Tôi đã gửi cùng một bài kiểm tra cho một số bạn bè trên các nền tảng khác nhau và mỗi người đều thất bại ít nhất một trong số đó. Không ai trong chúng ta có thể truy cập một trang web đã triển khai một cách ngây thơ bộ thử nghiệm được đề xuất và nội dung bị chặn dựa trên chúng. Tự kiểm tra và xem liệu bạn có bị chặn không

Nếu bạn chỉ kiểm tra một vài cấu hình trình duyệt và sau đó chặn nội dung dựa trên cấu hình đó thì chắc chắn bạn sẽ vô tình chặn mọi người. Ví dụ, một trong những bài kiểm tra được đề xuất – bài kiểm tra mà tác giả gọi là “mạnh mẽ nhất” của mình – là kích thước của một hình ảnh bị hỏng không bằng

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
5. Thử nghiệm này có thể đã hoạt động trong Chrome 59 nhưng không còn hoạt động trong Chrome 60. Để tạo ra thứ gì đó mạnh mẽ hợp pháp, thực tế bạn cần hỗ trợ một bộ thử nghiệm khác cho Chrome, Safari, Firefox, Chromium, Opera, Brave, v.v. và bạn cũng sẽ cần các bài kiểm tra theo phiên bản cụ thể và được cập nhật liên tục

Để triển khai tính năng lọc như thế này theo cách có trách nhiệm từ xa sẽ yêu cầu thực sự biết bạn đang làm gì và nó sẽ cần rất nhiều nỗ lực. Và để làm gì? . Bạn có thể chặn thành công Joe Schmoe, người đã vô hiệu hóa Trình cắm Chromium PDF do lo ngại về bảo mật, nhưng bất kỳ ai thực sự quan tâm đến gian lận quảng cáo, hack mũ đen hoặc–trời cấm—việc quét web sẽ không gặp bất kỳ khó khăn nào khi vượt qua bất kỳ bài kiểm tra nào mà bạn có thể . Nó giống như DRM;

Để giúp nhấn mạnh rằng những loại thử nghiệm này không thực sự hiệu quả trong thực tế, tôi quyết định xem qua và chỉ ra cách có thể bỏ qua từng loại thử nghiệm. Chỉ mất vài trăm dòng mã để giúp Chrome Headless thực hiện các bài kiểm tra tốt hơn so với Chrome tiêu chuẩn. Tất nhiên, những điều này sẽ không làm cho Chrome Headless không bị phát hiện trên toàn cầu, nhưng mọi thử nghiệm phức tạp hơn đều có thể dễ dàng bị bỏ qua theo những cách tương tự. Hy vọng rằng bạn sẽ thấy các kỹ thuật được đề xuất ở đây thú vị cho dù bạn đang thực hiện một số thao tác tìm kiếm trang web của riêng mình hay chỉ tò mò muốn xem nó được thực hiện như thế nào

Đây gần như là một trong những thử nghiệm được đề xuất duy nhất có thể xác định hợp pháp Chrome Headless, nhưng nó cũng là thử nghiệm tầm thường nhất để vượt qua. Tác nhân người dùng mặc định khi chạy Chrome ở chế độ không đầu sẽ giống như

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36

trong đó phần quan trọng mang lại điều đó là

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
6. Để thay đổi điều này, chúng tôi chỉ cần cung cấp cho Chrome tùy chọn dòng lệnh
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
7. Nếu bạn đang chạy Chrome trực tiếp từ dòng lệnh thì bạn chỉ cần thêm tùy chọn này ngoài tùy chọn
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
8

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"

Các tùy chọn tương tự có thể được chỉ định tương tự bằng cách sử dụng

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
9 nếu bạn đang sử dụng Python, Selenium và ChromeDriver

from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set

Cách tiếp cận hơi khác nếu bạn muốn sử dụng Giao thức Chrome DevTools, nhưng nó cũng tầm thường tương tự để thực hiện

________số 8

Tất cả các phương pháp này sẽ thay đổi tác nhân người dùng trong cả tiêu đề HTTP và

from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
0. Bây giờ đến những thử thách khó khăn hơn

Hai trong số các bài kiểm tra được đề xuất là để kiểm tra

from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
1 và
from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
2. Cả hai điều này có thể được bỏ qua bằng cách đưa JavaScript vào mỗi trang ghi đè lên
from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
3 với các giá trị mong muốn. Bây giờ chúng ta hãy tập trung vào JavaScript để mô phỏng các giá trị này. Chúng tôi sẽ quay lại và xem cách tiêm sau khi chúng tôi đã trải qua tất cả các bài kiểm tra vì tất cả chúng sẽ cần được tiêm cùng một lúc

Về cơ bản, chúng tôi chỉ muốn ghi đè lên các thuộc tính

from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
4 và
from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
5 trên
from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
6 bằng các giá trị sẽ vượt qua các bài kiểm tra của chúng tôi. Suy nghĩ đầu tiên của bạn có thể là chỉ đặt thuộc tính trực tiếp

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
6

nhưng điều này sẽ không thực sự ghi đè lên các giá trị vì đây là các thuộc tính chỉ sẵn sàng với các hàm getter làm bộ truy cập. Thay vào đó, chúng ta cần sử dụng

from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
7 để xác định lại các thuộc tính bằng các hàm getter mới. Điều này có thể được thực hiện như sau

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
8

Sau khi thực thi JavaScript này trên một trang,

from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
8 sẽ báo cáo
from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
9 và
const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
0 sẽ có độ dài là
const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
1. Các plugin có thể được mô phỏng sâu hơn, nhưng điều này không cần thiết trong trường hợp này vì bài kiểm tra mà chúng tôi đang bỏ qua chỉ kiểm tra độ dài của mảng

Proxy thông minh Intoli

Nếu bạn đang tìm kiếm web nghiêm túc, thì việc sử dụng proxy là điều bắt buộc. Dịch vụ Proxy thông minh Intoli của chúng tôi giúp bạn dễ dàng không bị chặn bởi các dịch vụ giảm thiểu bot. Các yêu cầu của bạn được định tuyến một cách thông minh thông qua các IP dân cư sạch, nơi chúng có khả năng thành công, các yêu cầu không thành công sẽ tự động được thử lại và thậm chí bạn có thể thực hiện các yêu cầu thông qua các trình duyệt từ xa được tải sẵn các tùy chỉnh khiến khó phát hiện ra trình quét của bạn. Nhập địa chỉ email của bạn vào bên dưới để có quyền truy cập vào cùng một công cụ mà chúng tôi sử dụng cho tất cả các công cụ quét web của riêng mình

Thử nghiệm tiếp theo tạo ngữ cảnh WebGL, sau đó kiểm tra chuỗi nhà cung cấp và trình kết xuất. Chuỗi nhà cung cấp của

const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
2 hoặc trình kết xuất của
const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
3 được cho là biểu thị Chrome Headless. Tôi không thể sao chép các chuỗi này trên máy của mình, nhưng hãy xem cách chúng ta có thể mô phỏng các giá trị này trong trường hợp chúng có mặt. Chúng tôi chỉ đơn giản là mã hóa cứng
const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
4 để trả về các chuỗi trình kết xuất và nhà cung cấp mong muốn của chúng tôi bằng cách sửa đổi nguyên mẫu cho
const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
5. Sửa đổi nguyên mẫu đảm bảo rằng phiên bản đã vá của chúng tôi sẽ được gọi trên bất kỳ phiên bản nào của
const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
6 được tạo (e. g. bằng cách thực hiện
const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
7)

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
9

Phiên bản đã vá này của

const CDP = require('chrome-remote-interface');

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

CDP(async function(client) {
  const {Network, Page} = client;
  await Page.enable();
  await Network.enable();
  await Network.setUserAgentOverride({userAgent});

  // user-agent is now set
});
8 trả về các giá trị mong muốn cho trình kết xuất và nhà cung cấp trong khi chuyển sang triển khai tiêu chuẩn cho bất kỳ giá trị tham số nào khác. Các số nguyên ở đây là các hằng số tiêu chuẩn xác định duy nhất các tham số

Chúng tôi đã đề cập rằng thử nghiệm hình ảnh bị hỏng không thực sự hợp lý vì Chrome 60 báo cáo kích thước hình ảnh là

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
5 đối với hình ảnh bị hỏng. Chúng ta hãy xem làm thế nào chúng ta có thể làm điều này, chỉ để cho thấy rằng nó cũng dễ dàng bỏ qua. Cách tiếp cận này kết hợp một vài kỹ thuật mà chúng tôi đã sử dụng

Chúng tôi sẽ sửa đổi nguyên mẫu một lần nữa, lần này là vào năm 160, để những thay đổi chúng tôi thực hiện sẽ áp dụng cho bất kỳ hình ảnh nào được tạo trong DOM. Cả

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
61 và
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
62 đều là các thuộc tính có bộ truy cập, vì vậy chúng tôi cũng cần sử dụng
from selenium import webdriver

user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'

options = webdriver.ChromeOptions()
# specify headless mode
options.add_argument('headless')
# specify the desired user agent
options.add_argument(f'user-agent={user_agent}')
driver = webdriver.Chrome(chrome_options=options)

# user-agent is now set
7 để ghi đè lên các phương thức getter của chúng. Chúng tôi sẽ trả lại chiều rộng và chiều cao của
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
64 cho hình ảnh bị hỏng và nếu không thì chỉ cần trì hoãn triển khai getter tiêu chuẩn

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
7

Cái này phức tạp hơn một chút so với một số cái trước đó, nhưng nó vẫn khá đơn giản

Phương pháp cuối cùng được đề xuất là phát hiện hỗ trợ cho đường chân tóc võng mạc bằng thư viện Modernizr. Đây là một thử nghiệm khác không thực sự có ý nghĩa vì phần lớn mọi người không có màn hình HiDPI và hầu hết các trình duyệt của người dùng sẽ không hỗ trợ tính năng này. Tuy nhiên, việc bỏ qua sẽ là chuyện nhỏ ngay cả khi nó có ý nghĩa khi sử dụng như một bài kiểm tra.

Chúng ta có thể thấy từ nguồn Modernizr, rằng bài kiểm tra về cơ bản là chèn thẻ

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
65 có id là
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
66 vào trang cùng với biểu định kiểu sau

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
0

Sau đó, thuộc tính

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
67 của
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
65 được kiểm tra và nếu thuộc tính này có giá trị là
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
69 thì tính năng đường chân tóc được hỗ trợ. Tất cả những gì chúng ta cần làm ở đây là sửa đổi nguyên mẫu của
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
80 sao cho
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
67 trả về
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
69 nếu id là
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
66. Mô hình cơ bản này sẽ trở nên khá quen thuộc bây giờ…

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
8

Đối mặt với những thách thức độc đáo với Web Scraping?

Chúng tôi sẽ làm việc với bạn để xây dựng các giải pháp tùy chỉnh phù hợp với nhu cầu của bạn. Từ quét web đến học máy, các chuyên gia của chúng tôi luôn sẵn sàng trợ giúp

Bắt đầu ngay bây giờ

Tại thời điểm này, chúng tôi có một loạt đoạn mã JavaScript sẽ bỏ qua các bài kiểm tra Headless của Chrome. Chúng tôi chỉ cần Chrome thực thi chúng trước mã kiểm tra trên trang web mục tiêu. Có thể đưa JavaScript vào một trang bằng Selenium bằng cách sử dụng lệnh gọi tới

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
84, nhưng rất tiếc, lệnh này chỉ có thể được gọi sau khi sự kiện
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
85 của tài liệu đã kích hoạt. Điều này có nghĩa là nếu có một thử nghiệm đồng bộ chặn tải trang thì nó sẽ chạy trước khi JavaScript được đưa vào có cơ hội giả lập nhiều thứ khác nhau mà các thử nghiệm đang kiểm tra

Nếu chúng tôi muốn vượt qua các bài kiểm tra một cách đáng tin cậy thì chúng tôi sẽ cần tìm cách đảm bảo rằng mã của chúng tôi chạy trước mã kiểm tra trên trang. Cách yêu thích của tôi để làm điều này là viết một Tiện ích mở rộng nhỏ của Chrome đưa thẻ

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
86 vào
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
87 của bất kỳ trang nào đã truy cập. Rất tiếc, Chrome Headless chưa hỗ trợ tiện ích mở rộng và có thể sẽ không hỗ trợ trong tương lai gần. Cho đến khi chức năng đó được thêm vào, chúng tôi sẽ cần sử dụng các phương pháp thay thế

Một cách mạnh mẽ hơn để đưa JavaScript vào một trang là thực sự sửa đổi HTML được yêu cầu trong chuyến bay và thêm thẻ

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
86 trước khi trình duyệt có cơ hội xem bản gốc. Đây là một kỹ thuật được sử dụng phổ biến hơn để phục vụ các phiên bản đã vá của tập lệnh riêng của trang web, nhưng nó có thể được áp dụng theo cách tương tự cho trường hợp sử dụng này. Chúng tôi sẽ sử dụng mitmproxy, một proxy HTTP có khả năng TLS rất dễ tạo tập lệnh, để chèn mã của chúng tôi

Trước tiên, chúng tôi sẽ cần cài đặt cả mitmproxy và BeautifulSoup4. Cả hai thứ này có thể có sẵn thông qua trình quản lý gói của hệ thống của bạn, nhưng bạn cũng có thể cài đặt chúng trong virtualenv bằng cách sử dụng

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
89 nếu muốn. Bây giờ chúng ta sẽ tạo một tập lệnh python ngắn có tên là
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
90 với các nội dung sau

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
0

Tập lệnh

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
90 xác định hàm
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
92 sẽ được gọi bởi mitmproxy trước mỗi phản hồi được ủy quyền. Nếu phản hồi có mã trạng thái
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
93 và loại nội dung là
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
94, thì chúng tôi sẽ đưa vào thẻ
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
86 của mình nội dung được tải từ
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
96.
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
96 ở đây chỉ chứa tất cả các bỏ qua kiểm tra JavaScript mà chúng tôi đã phát triển trong mỗi phần trước

Để bắt đầu proxy của chúng tôi với tập lệnh này, bây giờ chúng tôi có thể chạy như sau

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
1

Chúng tôi cũng phải yêu cầu Chrome sử dụng proxy của mình bằng cách chỉ định tùy chọn

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
98

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
2

Tùy chọn

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
8 có thể dự đoán sẽ yêu cầu Chrome chạy ở chế độ không đầu và
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
70 chỉ định giao diện gỡ lỗi mà chúng tôi sẽ sử dụng để giao tiếp và kiểm soát phiên bản. Bạn có thể chạy lệnh ngay bây giờ và nó sẽ chỉ ngồi và đợi chúng tôi kết nối với cổng gỡ lỗi sau vài phút

Chúng tôi sẽ sử dụng Giao diện từ xa của Chrome để thực sự kiểm soát phiên bản. Giao diện này hơi giống với Selenium, nhưng nó dành riêng cho Chrome và cho phép kiểm soát chi tiết hơn đối với một số thứ nhất định. Đặc biệt, nó cho phép chúng tôi chấp nhận các chứng chỉ tự ký từ mitmproxy. Điều này có thể thực hiện được với ChromeDriver vì

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
71 được chỉ định là một phần của thông số kỹ thuật W3, nhưng tính năng cụ thể này chưa được triển khai trong Chrome Headless

Để cài đặt Giao diện từ xa của Chrome, bạn có thể chạy

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
72 hoặc tương đương với trình quản lý gói mà bạn chọn. Sau khi nó được cài đặt, sau đó tạo một tệp có tên
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
73 với các nội dung sau

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
3

Tập lệnh này sẽ kết nối với phiên bản Headless Chrome hiện đang chạy của chúng tôi, truy cập trang thử nghiệm, lưu ảnh chụp màn hình sau 1 giây rồi thoát. Bản thân Chrome đã chạy và đã được định cấu hình để ủy quyền mọi thứ thông qua mitmproxy. Do đó, trang mà Chrome hiển thị phải bao gồm mã bỏ qua của chúng tôi trong thẻ

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3112.50 Safari/537.36
87 của tài liệu

Tất cả các phần hiện đã sẵn sàng và giờ đây chúng tôi có thể chạy tập lệnh với

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
75 (lưu ý rằng điều này sẽ yêu cầu phiên bản nút ít nhất 7. 6 do sử dụng async/await). Khi tập lệnh chạy, chúng ta sẽ thấy đầu ra tương tự như sau trong thiết bị đầu cuối
/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
76

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
4

Ngoài ra còn có một số lỗi, nhưng những lỗi này không có gì đáng lo ngại vì chúng là kết quả của việc khách hàng cần ghi đè các lỗi chứng chỉ. Bỏ qua những điều đó, có vẻ như chúng tôi đã thấy các yêu cầu dự kiến ​​và thẻ tập lệnh đã được đưa vào thành công trước khi trả về phản hồi

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
77

Cuối cùng, hãy xem

/opt/chrome/chrome-beta/chrome --headless \
    --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36"
78 đã tạo để xác minh rằng chúng tôi hiện đã vượt qua tất cả các bài kiểm tra

Nhà viết kịch lấy văn bản python

Chúng tôi đã vượt qua với màu sắc bay

Phải thừa nhận rằng đây là một phương pháp hơi phức tạp để bỏ qua các bài kiểm tra. Nhìn chung, sẽ dễ dàng hơn nếu chỉ cần vá các tập lệnh phát hiện của trang web để luôn vượt qua và sau đó cung cấp các phiên bản đã vá qua mitmproxy. Lý do tôi chọn con đường dài hơn này là vì tôi muốn thực sự nhấn mạnh rằng bản thân các bài kiểm tra không kiểm tra bất cứ thứ gì không thể dễ dàng giả mạo.

Đơn giản là không có cách nào để phân biệt một bot hoạt động tốt với người dùng. Và tại sao bạn nên cần? . Cuối cùng, bạn sẽ chặn những người dùng vô tội và các bot thông minh sẽ không bị phát hiện

Nếu bạn đang cố gắng loại bỏ một trang web hơi quá nhiệt tình với các cơ chế chặn của nó thì vui lòng liên hệ. Các thành viên trong nhóm của Intoli là những chuyên gia viết các bot hoạt động tốt không thể phân biệt được với người dùng. Ngoài ra, chúng tôi có thể giúp bạn áp dụng quy trình xác thực và phân tích dữ liệu tùy chỉnh để giúp bạn trích xuất giá trị từ dữ liệu của mình