-1

This part of the code responsible for the behavior launches the profile, prints a query in the search engine, goes to the query page, but freezes on it and does not do any more actions. Then he closes the page, opens a new empty one, writes a new query, and the situation goes around in a circle.

It is important that after entering the query and clicking the search, the script starts to run according to the results of this query. Open random pages, scroll through them, interact with them. And after opening 3-7 pages from the request and about 7-10 minutes of interaction with them. The loop opened a new search page - entered a new query and went through the pages. So that this cycle repeats.

And sometimes the following error is given:

Search error: 'NoneType' object is not subscriptable
Search error: 'NoneType' object is not subscriptable
[14:01:10] Critical error: 'NoneType' object is not subscriptable

My code is below:

class HumanBehavior:
    @staticmethod
    async def random_delay(a=1, b=5):
       
        base = random.uniform(a, b)
        await asyncio.sleep(base * (0.8 + random.random() * 0.4))

    @staticmethod
    async def human_type(page, selector, text):
        
        for char in text:
            await page.type(selector, char, delay=random.randint(50, 200))
            if random.random() < 0.07:
                await page.keyboard.press('Backspace')
                await HumanBehavior.random_delay(0.1, 0.3)
                await page.type(selector, char)
            if random.random() < 0.2 and char == ' ':
                await HumanBehavior.random_delay(0.2, 0.5)

    @staticmethod
    async def human_scroll(page):
       
        viewport_height = page.viewport_size['height']
        for _ in range(random.randint(3, 7)):
            scroll_distance = random.randint(
                int(viewport_height * 0.5), 
                int(viewport_height * 1.5)
            )
            if random.random() < 0.3:
                scroll_distance *= -1
            await page.mouse.wheel(0, scroll_distance)
            await HumanBehavior.random_delay(0.7, 2.3)

    @staticmethod
    async def handle_popups(page):
        
        popup_selectors = [
            ('button:has-text("Accept")', 0.7),
            ('div[aria-label="Close"]', 0.5),
            ('button.close', 0.3),
            ('div.cookie-banner', 0.4)
        ]
        for selector, prob in popup_selectors:
            if random.random() < prob and await page.is_visible(selector):
                await page.click(selector)
                await HumanBehavior.random_delay(0.5, 1.2)

async def perform_search_session(page):
    
    try:
       
        theme = "mental health"
        modifiers = ["how to", "best ways to", "guide for", "tips for"]
        query = f"{random.choice(modifiers)} {theme}"
        
        
        await page.goto("https://www.google.com", timeout=60000)
        await HumanBehavior.random_delay(2, 4)
        
       
        await HumanBehavior.handle_popups(page)
        
       
        search_box = await page.wait_for_selector('textarea[name="q"]', timeout=10000)
        await HumanBehavior.human_type(page, 'textarea[name="q"]', query)
        await HumanBehavior.random_delay(0.5, 1.5)
        await page.keyboard.press('Enter')
        
       
        await page.wait_for_selector('div.g', timeout=15000)
        await HumanBehavior.random_delay(2, 4)
        
        
        results = await page.query_selector_all('div.g a')
        if not results:
            print("No search results found")
            return False

        
        pages_to_open = random.randint(3, 7)
        for _ in range(pages_to_open):
            
            link = random.choice(results[:min(5, len(results))])
            await link.click()
            await page.wait_for_load_state('networkidle', timeout=20000)
            await HumanBehavior.random_delay(3, 6)
            
           
            await HumanBehavior.human_scroll(page)
            await HumanBehavior.handle_popups(page)
            
          
            internal_links = await page.query_selector_all('a')
            if internal_links:
                clicks = random.randint(1, 3)
                for _ in range(clicks):
                    internal_link = random.choice(internal_links[:10])
                    await internal_link.click()
                    await page.wait_for_load_state('networkidle', timeout=20000)
                    await HumanBehavior.random_delay(2, 5)
                    await HumanBehavior.human_scroll(page)
                    await page.go_back()
                    await HumanBehavior.random_delay(1, 3)
            
            
            await page.go_back()
            await page.wait_for_selector('div.g', timeout=15000)
            await HumanBehavior.random_delay(2, 4)
            
            
            results = await page.query_selector_all('div.g a')
            
        return True
        
    except Exception as e:
        print(f"Search error: {str(e)}")
        return False
1
  • 1
    always put full error message because there are other useful information. Commented Apr 9 at 15:34

1 Answer 1

1

There's two issues:

1.

'NoneType' object is not subscriptable, which is caused by page.viewport_size sometimes being None

Fix:

viewport = page.viewport_size or {"height": 800}
viewport_height = viewport['height']

Using page.go_back() doesn’t reliably brings back Google results. You shouldn't rely on go_back() — instead, start a fresh search each time:

await page.goto("https://www.google.com")
await HumanBehavior.human_type(page, 'textarea[name="q"]', new_query)
await page.keyboard.press('Enter')
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.