Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Can';t多次刮取从不同搜索中得到的不同结果,而不是单个结果_Python_Python 3.x_Web Scraping_Scrapy - Fatal编程技术网

Python Can';t多次刮取从不同搜索中得到的不同结果,而不是单个结果

Python Can';t多次刮取从不同搜索中得到的不同结果,而不是单个结果,python,python-3.x,web-scraping,scrapy,Python,Python 3.x,Web Scraping,Scrapy,我已经编写了一个脚本来解析从csv文件中获取的网页(名字和姓氏)中填写两个输入框时填充的链接名称。该csv文件包含数千个名称,我正试图使用这些名称来刮取链接的名称 问题是爬行器总是刮去姓氏的链接名称 如何刮取与每次搜索关联的个人链接名称? 这是几个按时间顺序排列的名字和姓氏供您参考[取自csv文件]: ANTONIO AMADOR ACOSTA JOHN ROBERT ADAIR ROBERT CURTIS ADAMEK CY RITCHIE

我已经编写了一个脚本来解析从csv文件中获取的网页(
名字和
姓氏)中填写两个输入框时填充的
链接名称
。该csv文件包含数千个名称,我正试图使用这些名称来刮取链接的名称

问题是爬行器总是刮去姓氏的
链接名称

如何刮取与每次搜索关联的个人
链接名称

这是几个按时间顺序排列的名字和姓氏供您参考[取自csv文件]:

ANTONIO AMADOR      ACOSTA 
JOHN ROBERT         ADAIR 
ROBERT CURTIS       ADAMEK 
CY RITCHIE          ADAMS 
我试过这样做:

import csv
import scrapy
from scrapy.crawler import CrawlerProcess

class AmsrvsSpider(scrapy.Spider):
    name = "amsrvsSpiderscript"
    lead_url = "https://amsrvs.registry.faa.gov/airmeninquiry/Main.aspx"

    def start_requests(self):
        with open("document.csv","r") as f:
            reader = csv.DictReader(f)
            itemlist = [item for item in reader]

        for item in itemlist:
            yield scrapy.Request(self.lead_url,meta={"fname":item['FIRST NAME'],"lname":item['LAST NAME']},dont_filter=True, callback=self.parse)

    def parse(self,response):
        fname = response.meta.get("fname")
        lname = response.meta.get("lname")
        payload = {item.css('::attr(name)').get(default=''):item.css('::attr(value)').get(default='') for item in response.css("input[name]")}
        payload['ctl00$content$ctl01$txtbxFirstName'] = fname
        payload['ctl00$content$ctl01$txtbxLastName'] = lname
        payload.pop('ctl00$content$ctl01$btnClear')
        yield scrapy.FormRequest(self.lead_url,formdata=payload,dont_filter=True,callback=self.parse_content)

    def parse_content(self,response):
        name = response.css("a[id$='lnkbtnAirmenName']::text").get()
        print(name)


if __name__ == "__main__":
    c = CrawlerProcess({
        'USER_AGENT': 'Mozilla/5.0',
        'DOWNLOAD_TIMEOUT' : 5,
        'LOG_LEVEL':'ERROR'
    })
    c.crawl(AmsrvsSpider)
    c.start()
该站点中的结果如下所示:

电流输出:

CY RITCHIE  ADAMS 
CY RITCHIE  ADAMS 
CY RITCHIE  ADAMS 
CY RITCHIE  ADAMS 
预期产出:

ANTONIO AMADOR  ACOSTA 
JOHN ROBERT     ADAIR 
ROBERT CURTIS   ADAMEK 
CY RITCHIE      ADAMS 

您的url在一次请求后被过滤,这就是为什么它不会删除其他链接的原因。您可以添加自定义设置
dont\u filter=True
,以避免重复URL
您可以参考以进一步了解

首先,我认为您遇到的问题来自如何将
DictReader
对象转换为列表

打印
itemlist
将提供:

[OrderedDict([('ANTONIO AMADOR','JOHN ROBERT'),('ACOSTA','ADAIR')]),OrderedDict([('ANTONIO AMADOR','ROBERT CURTIS'),('ACOSTA','ADAMEK')]),OrderedDict([('ANTONIO AMADOR','CY RITCHIE'),('ACOSTA','ADAMS'))]
我认为这不是你想要的。为了解决这个问题,我使用了
csv.reader(f)
,它将每一行读取为
(fname,lname)
元组

我还做了一些其他更改,据我所知,没有必要一次又一次地请求表单页面,因此只需请求一次,然后为列表中的每个名称提交表单

最后,我还改变了空白的使用,只是为了提高我自己的可读性

导入csv
进口羊瘙痒
从scrapy.crawler导入crawler进程
AmsrvsSpider类(刮擦式卡盘):
name=“amsrvsSpiderscript”
导联url=”https://amsrvs.registry.faa.gov/airmeninquiry/Main.aspx"
起始URL=[”https://amsrvs.registry.faa.gov/airmeninquiry/Main.aspx"]
def解析(自我,响应):
以open(“document.csv”、“r”)作为f:
拆分名称=列表(csv.reader(f))
打印(拆分名称)
默认值_pload={item.css('::attr(name)').get(默认值=''):
css('::attr(value)').get(默认值=“”)
对于response.css中的项(“输入[名称]”)
}
默认\u pload.pop('ctl00$content$ctl01$btnClear'))
对于fname,拆分名称中的lname:
有效载荷=dict(默认载荷)
有效负载['ctl00$content$ctl01$txtbxFirstName']=fname
有效负载['ctl00$content$ctl01$txtbxLastName']=lname
打印(fname,lname)
生成scrapy.FormRequest(self.lead\u url,
formdata=有效载荷,
Don_filter=True,
callback=self.parse_内容
)
def解析_内容(自身、响应):
name=response.css(“a[id$='lnkbtnAirmenName']::text”).get()
印刷品(名称)
如果名称=“\uuuuu main\uuuuuuuu”:
c=爬网进程({
“用户代理”:“Mozilla/5.0”,
“下载超时”:5,
“日志级别”:“错误”
})
c、 爬行(AmsrvsSpider)
c、 开始()
这解决了您无法为每个名称生成请求的问题,并检索了所需的链接名称

请注意,我用于测试的document.csv如下所示:

ANTONIO AMADOR,ACOSTA 
JOHN ROBERT,ADAIR 
ROBERT CURTIS,ADAMEK 
CY RITCHIE,ADAMS 

我不确定到底出了什么问题,但您可以跳过
parse()

输出:

ANTONIO AMADOR  ACOSTA  
ROBERT CURTIS  ADAMEK  
CY RITCHIE  ADAMS  
JOHN ROBERT  ADAIR  

这就是我成功的原因。事实证明,饼干在这里起着至关重要的作用。因此,有必要以正确的方式处理cookie以获得所需的输出。我还在
settings.py
中使用了这个
COOKIES\u ENABLED=True

工作脚本:

def get_fields():
    with open("brian.csv","r") as f:
        reader = csv.DictReader(f)
        itemlist = [item for item in reader]
    return itemlist

class AmsrvsSpider(scrapy.Spider):
    name = "amsrvs"
    lead_url = 'https://amsrvs.registry.faa.gov/airmeninquiry/Main.aspx'
    start_urls = ['https://amsrvs.registry.faa.gov/airmeninquiry/Main.aspx']

    def parse(self,response):
        payload = {item.css('::attr(name)').get(default=''):item.css('::attr(value)').get(default='') for item in response.css("input[name]")}
        payload.pop('ctl00$content$ctl01$btnClear')

        for i,item in enumerate(get_fields()):
            payload['ctl00$content$ctl01$txtbxFirstName'] = item['FIRST NAME']
            payload['ctl00$content$ctl01$txtbxLastName'] = item['LAST NAME']
            yield scrapy.FormRequest(self.lead_url,formdata=payload,meta={'cookiejar': i},dont_filter=True,callback=self.parse_result)

    def parse_result(self,response):
        item_content = response.css("[id$='lnkbtnAirmenName']::text").get()
        print(item_content)

这可能是由于一个错误。你能调试代码吗?你能添加你的日志吗?是的,你就在那里。但是,即使在我使用该
dont\u filter=True
时,也会出现另一个问题。脚本总是为不同的名字生成相同的信息,这意味着我使用了几个名字来获取他们的信息,但是脚本一次又一次地填充关于姓氏的信息。谢谢你的回答@Calimocho。它仍然多次产生相同的结果。这很奇怪,在我的机器上复制和粘贴上面的代码会产生您上面概述的预期输出。我会再次检查所有内容是否完全相同,如果您仍然有问题,每个名称可能需要它自己的初始请求和cookie jar。默认情况下,处理启用的cookie,因此设置
cookies\u enabled=True
不会更改脚本的行为。但是,您的使用
cookiejar
meta-key确实如此。在您的实现中,
…meta={'cookiejar':i}
将创建
i
独立的会话。
def get_fields():
    with open("brian.csv","r") as f:
        reader = csv.DictReader(f)
        itemlist = [item for item in reader]
    return itemlist

class AmsrvsSpider(scrapy.Spider):
    name = "amsrvs"
    lead_url = 'https://amsrvs.registry.faa.gov/airmeninquiry/Main.aspx'
    start_urls = ['https://amsrvs.registry.faa.gov/airmeninquiry/Main.aspx']

    def parse(self,response):
        payload = {item.css('::attr(name)').get(default=''):item.css('::attr(value)').get(default='') for item in response.css("input[name]")}
        payload.pop('ctl00$content$ctl01$btnClear')

        for i,item in enumerate(get_fields()):
            payload['ctl00$content$ctl01$txtbxFirstName'] = item['FIRST NAME']
            payload['ctl00$content$ctl01$txtbxLastName'] = item['LAST NAME']
            yield scrapy.FormRequest(self.lead_url,formdata=payload,meta={'cookiejar': i},dont_filter=True,callback=self.parse_result)

    def parse_result(self,response):
        item_content = response.css("[id$='lnkbtnAirmenName']::text").get()
        print(item_content)