【问题标题】:Request multiple urls in Python scraping script在 Python 抓取脚本中请求多个 url
【发布时间】:2019-09-30 07:32:18
【问题描述】:

我正在创建一个网络抓取工具,并尝试请求多个共享相同 url 路径的 url,但编号 id 除外。

我抓取一个网址的代码如下:

import requests
from bs4 import BeautifulSoup as bs

r = requests.get('https://beta.companieshouse.gov.uk/company/00930291/officers')
soup = bs(r.content, 'lxml')
names = [item.text.strip() for item in soup.select('[class^=appointment]:not(.appointments-list):has([id^="officer-role-"]:contains(Director)) h2')]
print(names)

除了公司编号之外,网址具有相同的结构。我尝试了以下代码来尝试让它抓取多个页面,但没有成功:

import requests
from bs4 import BeautifulSoup as bs

pages = []

for i in range(11003058, 11003059, 00930291):
```url = 'https://beta.companieshouse.gov.uk/company/' + str(i) + '/officers'
```pages.append(url)

for item in pages:
```page = requests.get(item)
```soup = bs(page.text, 'lxml')

names = [item.text.strip() for item in soup.select('[class^=appointment]:not(.appointments-list):has([id^="officer-role-"]:contains(Director)) h2')]

print(names)

这只是给了我第一页(/11003058/officers),为什么它没有循环通过它们?有人可以帮忙吗?

【问题讨论】:

    标签: python python-3.x loops url request


    【解决方案1】:

    这应该可以解决您的问题:

    range() 函数返回一个数字序列,默认从 0 开始,并且 递增 1(默认),并以指定的数字结束。

    语法:

     range(start, stop, step)
    

    https://docs.python.org/3/library/functions.html#func-range

    将您的代码替换为:

    company_id = ["11003058","11003059","00930291"]
    
    for i in company_id:
        url = 'https://beta.companieshouse.gov.uk/company/' + str(i) + '/officers'
        pages.append(url)
    

    您应该在迭代页面之前将 soup 初始化为列表:

    汤=[]

    并附加在汤列表中:

    for item in pages:
      page = requests.get(item)
      soup.append(bs(page.text, 'lxml'))
    

    打印姓名列表:

    names = []
    for items in soup:
        h2Obj = items.select('[class^=appointment]:not(.appointments-list):has([id^="officer-role-"]:contains(Director)) h2')
        for i in h2Obj:
            tagArray = i.findChildren()
            for tag in tagArray:
                if isinstance(tag,Tag) and tag.name in 'a':
                    names.append(tag.text)
    

    O/P:

    ['MASRAT, Suheel', 'MARSHALL, Jack', 'SUTTON, Tim', 'COOMBES, John Frederick', 'BROWN, Alistair Stuart', 'COOMBES, Kenneth', 'LAFONT, Jean-Jacques Mathieu', 'THOMAS-KEEPING, Lindsay Charles', 'WILLIAMS, Janet Elizabeth', 'WILLIAMS, Roderick', 'WRAGG, Barry']
    

    添加脚本顶部:

    从 bs4.element 导入标签

    【讨论】:

    • 感谢您的帮助。这有效,但仅显示其来源的网址。如何合并 names= 部分,以便打印名称而不是页面 url?
    • names = [item.text.strip() for item in soup.select('[class^=appointment]:not(.appointments-list):has([id^="officer-角色-"]:contains(Director)) h2')]
    • 我已经在新的 soup.append... 之后添加了 names=... 并添加了 print(names),但它出现了这个错误:AttributeError: 'list ' 对象没有属性 'select'。我做错了什么:-(
    • 因为名字有list实例类型,需要再迭代一次
    • 你是绝对的明星!!效果很好,非常感谢:-)
    【解决方案2】:

    range 的语法是 range(start, stop, step)。它从start 循环到stop - 1 并每次增加step。你在这里做了一些奇怪的事情,因为在你的情况下 stop 等于 start + 1 所以它只会循环一次,使用 start 值。

    我想你只是想获得这 3 个网址:

    for i in (11003058, 11003059, 00930291):
    

    【讨论】:

      【解决方案3】:

      循环范围:循环在迭代过程中始终包含 start_value 并排除 end_value

      试试这个:

      import requests
      from bs4 import BeautifulSoup as bs
      
      pages = ['11003058', '11003059', '00930291']
      i=0
      while i<len(pages):
        url = 'https://beta.companieshouse.gov.uk/company/' + pages(i) + '/officers'
        pages.append(url)
        i+1
      
      for item in pages:
        page = requests.get(item)
        soup = bs(page.text, 'lxml')
      
      names = [item.text.strip() for item in soup.select('[class^=appointment]:not(.appointments-list):has([id^="officer-role-"]:contains(Director)) h2')]
      
      print(names)
      

      【讨论】:

      • 感谢您的帮助。我试过你的代码,但它出现错误:文件“444.py”,第 6 行,在 while i
      • 哦,对不起,我忘了定义'i',现在你可以运行它了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 2017-05-21
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多