【问题标题】:Script crawls only the first page instead of multiple pages脚本只抓取第一页而不是多页
【发布时间】:2020-01-12 23:43:09
【问题描述】:

我正在尝试抓取网站的多个页面。但是程序只能抓取第一页。

import requests
from bs4 import BeautifulSoup
import re
import json
import time

def make_soup(url):

    source = requests.get(url).text
    soup = BeautifulSoup(source, 'lxml')

    pattern = re.compile(r'window.__WEB_CONTEXT__={pageManifest:(\{.*\})};')
    script = soup.find("script", text=pattern)
    jsonData = pattern.search(script.text).group(1)

    pattern_number = re.compile(r'\"[0-9]{9,12}\":(\{\"data\":\{\"cachedFilters\":(.*?)\}\}),\"[0-9]{9,11}\"')
    jsonData2 = pattern_number.search(jsonData).group(1)

    dictData = json.loads(jsonData2)
    return dictData

def get_reviews(dictData):

    """ Return a list of five dicts with reviews.
    """

    all_dictionaries = []

    for data in dictData['data']['locations']:
        for reviews in data['reviewListPage']['reviews']:

            review_dict = {}

            review_dict["reviewid"] = reviews['id']
            review_dict["reviewurl"] =  reviews['absoluteUrl']
            review_dict["reviewlang"] = reviews['language']
            review_dict["reviewdate"] = reviews['createdDate']

            userProfile = reviews['userProfile']
            review_dict["author"] = userProfile['displayName']

            all_dictionaries.append(review_dict)

    return all_dictionaries

def main():

    url = 'https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-Coronado_Hotel-Zurich.html#REVIEWS'

    dictData = make_soup(url)
    review_list = get_reviews(dictData) # list with five dicts
    #print(review_list)

    page_number = 5

    while page_number <= 260: # number in the URL
        next_url = 'https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-or' + str(page_number) + '-Coronado_Hotel-Zurich.html#REVIEWS'
        dictData = make_soup(url)
        review_list2 = get_reviews(dictData)
        print(review_list2)

        page_number += 5
        time.sleep(0.5)

if __name__ == "__main__":
    main()

我不确定是否可以使用此 URL 抓取多个页面。在网站上有 54 个页面,但在 URL 中我总是要添加数字 5,如下所示:

Page 1
https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-Coronado_Hotel-Zurich.html#REVIEWS

Page2
https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-or5-Coronado_Hotel-Zurich.html#REVIEWS

Page3
https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-or10-Coronado_Hotel-Zurich.html#REVIEWS

我不知道这是否是个好主意。 你有什么建议吗?先感谢您!

【问题讨论】:

  • 我不确定我是否理解您在以开头的段落中的意思,而且我不确定我是否可以爬......
  • 抱歉 :-D 好吧,可以这样说:我可以用这个 URL 抓取多个页面吗?
  • 你试过了吗?据我所知,使用or5or10 等它应该读取页面。很久以前有类似的问题,我可能使用or5or10 来回答阅读页面。这里是this answer。在代码中,您应该在 Stackoverflow 上找到问题的链接。
  • @furas 非常感谢!您的代码输出的正是我所需要的 :-) 首先,我还尝试用 scrapy 抓取这个网站,但是为了抓取评级,我不得不更改为 json。您知道为什么我上面的代码不适用于多个页面吗?

标签: python web-scraping web-crawler


【解决方案1】:

您将新网址分配给next_url,但您使用url 来阅读页面。

next_url = 'https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-or' + str(page_number) + '-Coronado_Hotel-Zurich.html#REVIEWS'
dictData = make_soup(url)

你必须重命名变量

url = 'https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-or' + str(page_number) + '-Coronado_Hotel-Zurich.html#REVIEWS'
dictData = make_soup(url)

【讨论】:

  • 即使我一开始没有看到这个错误 - 我必须在 make_soup() 中使用 print(url) 才能看到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 2020-03-27
  • 2023-03-30
  • 2017-06-22
  • 2023-01-24
  • 1970-01-01
  • 2018-02-12
相关资源
最近更新 更多